0

How can I to substract/delete/remove all coincident elements from an array list within another array list using .filter() of ES6 javascript?

Jquery's solution is also accepted, but any solution must be IE11+ and Chrome iOs compatible. Avoid using external libraries (except jquery). This is what I tried so far:

   var originList = [
        {"id":1,"name":"www"},
     {"id":2, "name":"fff"},
     {"id":3, "name":"ddd"},
     {"id":4, "name":"aaaa"},
     {"id":5, "name":"zzzz"},
     {"id":6, "name":"Susane"},
        {"id":7,"name":"yyy"}
    ];

    var rest = [
        {"id":1,"name":"www"},
     {"id":2, "name":"fff"},
     {"id":3, "name":"ddd"},
        {"id":4, "name":"aaaa"},
        {"id":5, "name":"zzzz"},
    ];

    var newList = [];
    var list = [];

    $.each(originList, function(id,data){
       list = originList.filter(function(obj,a){
      return data.id !== obj.id ? obj : false;
     });
    });


    $.each(originList, function(id,data){
        $.each(rest, function(alli,allData){
      if(data.id === allData.id) {
         newList[id] = data;
      }
  
     });
    });

    console.log(list); //does not exclude id:6
    console.log(newList); //this result is what I want
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Alex
  • 643
  • 7
  • 17

6 Answers6

3

You can use filter and find for the newer version.

var originList = [
  {"id":1,"name":"www"},
  {"id":2, "name":"fff"},
  {"id":3, "name":"ddd"},
  {"id":4, "name":"aaaa"},
  {"id":5, "name":"zzzz"},
  {"id":6, "name":"Susane"},
  {"id":7,"name":"yyy"}
];
 
var rest = [
  {"id":1,"name":"www"},
  {"id":2, "name":"fff"},
  {"id":3, "name":"ddd"},
  {"id":4, "name":"aaaa"},
  {"id":5, "name":"zzzz"},
];
 
var newList = originList.filter( o => rest.find( x => o.id === x.id ) );
 
console.log( newList );

Doc: .filter(), .find()


Can use for and if for the older version.

var originList = [
  {"id":1,"name":"www"},
  {"id":2, "name":"fff"},
  {"id":3, "name":"ddd"},
  {"id":4, "name":"aaaa"},
  {"id":5, "name":"zzzz"},
  {"id":6, "name":"Susane"},
  {"id":7,"name":"yyy"}
];
 
var rest = [
  {"id":1,"name":"www"},
  {"id":2, "name":"fff"},
  {"id":3, "name":"ddd"},
  {"id":4, "name":"aaaa"},
  {"id":5, "name":"zzzz"},
];

var newList = [];
for (var i = 0; i < originList.length; i++) {
  for (var x = 0; x < rest.length; x++) {
    if ( rest[x].id === originList[i].id ) {
        newList.push( originList[i] );
        break;
    }
  }
}

console.log( newList );
Eddie
  • 26,593
  • 6
  • 36
  • 58
  • Ohh.. Ill update it in a bit :) – Eddie Mar 02 '18 at 16:55
  • For IE10+ compatibility, could I suggest using a transpiler & pollyfill's, writing code for older browsers lack of features is worse than a red hot poker in the eye. – Keith Mar 02 '18 at 17:02
  • Updated. Just use `if` and `for` – Eddie Mar 02 '18 at 17:08
  • 1
    What I need its just the opposite the values your `newList` is returning – Alex Mar 02 '18 at 17:10
  • @AXL Updated. :) – Eddie Mar 02 '18 at 17:11
  • @Andreas Hahah.. Updated too – Eddie Mar 02 '18 at 17:12
  • Those are the expect values, yes. But if you notice in my question I already have a solution (pretty) like yours to get those expect values. I was trying to get a `ES6` solution using `.filter` function. Also updated my question, I just need IE11+ compatibility. Thanks! – Alex Mar 02 '18 at 17:13
  • 1
    @AXL IE10 or IE11... Most or rather all ES6 features are not available in any of those browsers: https://kangax.github.io/compat-table/es6/ – Andreas Mar 02 '18 at 17:23
1

var originList = [
  {"id":1,"name":"www"},
  {"id":2, "name":"fff"},
  {"id":3, "name":"ddd"},
  {"id":4, "name":"aaaa"},
  {"id":5, "name":"zzzz"},
  {"id":6, "name":"Susane"},
  {"id":7,"name":"yyy"}
];
 
var rest = [
  {"id":1,"name":"www"},
  {"id":2, "name":"fff"},
  {"id":3, "name":"ddd"},
  {"id":4, "name":"aaaa"},
  {"id":5, "name":"zzzz"},
];

function containsObject(obj, list) {
  for (var i = 0; i < list.length; i++) {
    if (list[i].id === obj.id) return true;
  }
  return false;
}
 
var newList = originList.filter(function(item){  return !containsObject(item, rest)
});
 
console.log( newList );
fyasir
  • 2,924
  • 2
  • 23
  • 36
  • Good catch. going to change it – fyasir Mar 02 '18 at 17:08
  • I see IE [does support `filter()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter#Browser_compatibility) – Alex Mar 02 '18 at 17:17
  • But IE doesn't support arrow function. So I changed the arrow function – fyasir Mar 02 '18 at 17:23
  • What is the return false statement on the *containsObject* function for? – Alex Mar 02 '18 at 17:47
  • @AXL The function passed to `.filter()` has to return `true` (keep the element) or `false` (get rid of the element). Check the documentation you've linked. – Andreas Mar 02 '18 at 17:53
  • I ask about the return false out of the loop and if comparisson. The last step will always be a returning false statement no matter what. That's what I dont get. I guess you could put an `else` with a return false, isn't? – Alex Mar 02 '18 at 17:55
  • @AXL The function returns `true` if `list` contains an element which has the same `id` as `obj`. Only if all elements in `list` have a different `id` than `obj` it returns `false`. An `else` branch would only check the first element in `list` – Andreas Mar 02 '18 at 18:24
0

you can try this

var value1s = {};
arr1.forEach(function(item) {
  value1s[item.id] = item.name;
});

arr2.forEach(function(item) {
  if (item.id in value1s) {
    theFunction(value1s[item.id], item.name);
  }
});

function theFunction(id, name) {
   console.log("{"+id + ":" + name+"}");
}
zetawars
  • 1,023
  • 1
  • 12
  • 27
0

If you have lodash at your disposal, you can use the function _.differenceWith and pass _.isEqual as the comparator invoked per element (if you want total equality) or a custom comparator if you only want to compare some properties of the object to determine equality.

Lodash also grants you browser compatibility.

Hope it helps.

var originList = [
  {"id":1,"name":"www"},
  {"id":2, "name":"fff"},
  {"id":3, "name":"ddd"},
  {"id":4, "name":"aaaa"},
  {"id":5, "name":"zzzz"},
  {"id":6, "name":"Susane"},
  {"id":7,"name":"yyy"}
];
 
var rest = [
  {"id":1,"name":"www"},
  {"id":2, "name":"fff"},
  {"id":3, "name":"ddd"},
  {"id":4, "name":"aaaa"},
  {"id":5, "name":"zzzz"},
];

console.log(_.differenceWith(originList, rest, _.isEqual));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.js"></script>
acontell
  • 6,792
  • 1
  • 19
  • 32
0

var originList = [
    {"id":1,"name":"www"},
    {"id":2, "name":"fff"},
    {"id":3, "name":"ddd"},
    {"id":4, "name":"aaaa"},
    {"id":5, "name":"zzzz"},
    {"id":6, "name":"Susane"},
    {"id":7,"name":"yyy"}
];

var rest = [
    {"id":1,"name":"www"},
    {"id":2, "name":"fff"},
    {"id":3, "name":"ddd"},
    {"id":4, "name":"aaaa"},
    {"id":5, "name":"zzzz"},
];

const newList = originList.filter(function(originListVal) {
  return rest.reduce(function(currentVal, nextRestVal) {
    return currentVal || originListVal.id === nextRestVal.id;
  }, false);
});

console.log(newList);
th3n3wguy
  • 3,649
  • 2
  • 23
  • 30
0
let newList = originList.filter(ele => !rest.some(fil => ele.id === fil.id));

If cannot use arrow functions

let newList = originList.filter(function(ele) {
  return rest.some(function(fil) {
    return ele.id === fil.id;
  });
});
AZ_
  • 3,094
  • 1
  • 9
  • 19