3

I'm trying to subtract, i.e. remove, multiple objects, namely the objects of array2 found in array1 so that the end result is that array2 only contains the "jean" object.

Help! I'm lost.

I tried multiple times code like the following example but it didn't worked.

array1= [{"caracname" : "charles"}, {"caracname" : "kevin"}]
array2= [{"caracname" : "charles"}, {"caracname" : "kevin"}, {"caracname" : "jean"}]
            
            array1.forEach(function (k) {
                delete array2[k];
            });
            
            console.log(array2);

1

4 Answers 4

3

A bit easier with a libraries like Lodash :

var array1 = [{"caracname" : "charles"}, {"caracname" : "kevin"}];
var array2 = [{"caracname" : "charles"}, {"caracname" : "kevin"}, {"caracname" : "jean"}];

var array3 = _.differenceWith(array2, array1, _.isEqual);

console.log( JSON.stringify(array3) );

// or 
_.pullAllWith(array2, array1, _.isEqual);

console.log( JSON.stringify(array2) );
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>


A bit less efficient alternative without library (might not work for objects with more than one property) :

var array1 = [{"caracname" : "charles"}, {"caracname" : "kevin"}];
var array2 = [{"caracname" : "charles"}, {"caracname" : "kevin"}, {"caracname" : "jean"}];

var j = JSON.stringify, array3 = array2.filter(e => array1.map(j).indexOf(j(e)) < 0);

console.log( j(array3) );

Sign up to request clarification or add additional context in comments.

Comments

2

Here is how to do this:

function objectsEqual(o1, o2) {
    return o1.caracname === o2.caracname
}

function subtractArrays(a1, a2) {
    var arr = [];
    a1.forEach((o1) => {
       var found = false;
       a2.forEach((o2) => {
           if (objectsEqual(o1, o2)) {
                found = true;
           }  
       });
       if (!found) {
           arr.push(o1);
       }
    })
    return arr;
}

console.log(subtractArrays(array2, array1));

fixed in plunker: https://plnkr.co/edit/vA6oWg9R44f6k7ylyFh6?p=preview

2 Comments

The console.log show undefined: plnkr.co/edit/CeQgUyhwh3cpYEPwmD30?p=preview
Fixed and added plunker
1

As it turns out deleting an array element is not as easy as deleting a variable; see here. The "deleted" element is not deleted but acquires an undefined value while the length of the array stays the same.

Found some helpful advice here. So, you may use array2's splice method which according to MDN handily does the following:

The splice() method changes the contents of an array by removing existing elements and/or adding new elements.

The following snippet works irrespective of the order of the elements in each array, as follows:

var arr1 = [{
  "caracname": "charles"
}, {
  "caracname": "kevin"
}];

var arr2 = [{
  "caracname": "charles"
}, {
  "caracname": "jean"
}, {
  "caracname": "kevin"
}];

var tmp1 = "",
    tmp2 = "";

for (var k = 0, key = "", maxLength = arr1.length; k < maxLength; k++) {
  key = Object.keys(arr1[k])[0];
  
  for (var j = 0, maxLength_2 = arr2.length; j < maxLength_2; j++) {
  
    tmp2 = arr2[j][key];
    tmp1 = arr1[k][key];
  
  if (tmp2 === tmp1) {
      arr2.splice(j, 1);
      maxLength_2--; // array2 length now one less
      break;
    }// end if
  }// end inner-for
}// end outer-for

console.log(arr2);

I've revised this example after running the code here, altering some variable names as a result.

As an aside, you should declare your arrays with var or optionally let; more info here and here.

2 Comments

"proper" object comparison is not easy stackoverflow.com/questions/1068834/… (that's why I didn't even attempt it in my answer, but just compared their JSON string representations, and Nayish compares just the values of the caracname properties). Pasting JavaScript in the TypeScript typescriptlang.org/play or similar editor, might be helpful to notice some of the issues (not sure if using the array from Object.keys as string [key] is intentional)
@Slai Thanks for this info. I fixed the code so that now var key holds a string value. Tested code and it seems okay now when I run it at the Typescript website.
0

Use this code: [ advised by @slevy1 ]

var array1= [{"caracname" : "charles"}, {"caracname" : "kevin"}]
var array2= [{"caracname" : "charles"}, {"caracname" : "kevin"}, {"caracname" : "jean"}]

array1.forEach(function (k) {
    var index = array1.valueOf(k);
    array2.splice(index, 1);
});

array2.forEach(function (o) {
    console.log(o.caracname);
});

codepen link

5 Comments

I ran your code here codepen.io/anon/pen/KXGZPv?editors=1111 and didn't get the intended result.
Hi @slevy1, thank you for your effort. I've edited(fixed) my code and it is working now. Please test again bro.
@Fatih index is not a number (try console.log(index)) and array2.splice just removes the first item
@Fatih Indeed your code does work, so I give you my upvote. I ran your code at codepen.io/anon/pen/wrYmrv?editors=1111 and made a few changes, namely your arrays should be declared with either var or let. Secondly I changed the "k" to "o" for the parameter of the anonymous function to remind users that the parameter is an object.
Thank you @slevy1 for your advice.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.