简体   繁体   中英

Javascript, Iterating through two arrays of objects and adding an item from one to another “if it doesn't exist”

I have two arrays, one contains values as strings and the other as integers, as silly as it might be but I got stuck on it and I need a little help, I want to iterate through both and if arr1 contains an item that doesn't exist in arr2, it will be pushed to a newArray

here is what I tried

 const arr1 = [ {id: 1, user_id: 1}, {id: 2, user_id: 2}, {id: 3, user_id: 3}, {id: 4, user_id: 4}, ] const arr2 = [ {id: '1', user_id: '1'}, {id: '2', user_id: '2'}, {id: '3', user_id: '3'}, ] const newArray = [] for (const x of arr1) { for (const y of arr2) { if (x.id !== +y.id) { newArray.push(x); break; } } } console.log(newArray); 

this adds all items in arr1, what I want to be pushed to newArray instead is only the item that exists in arr1 and not in arr2

thanks in advance!

You could take a Set and filter known items out.

 const arr1 = [{ id: 1, user_id: 1 }, { id: 2, user_id: 2 }, { id: 3, user_id: 3 }, { id: 4, user_id: 4 }], arr2 = [{ id: '1', user_id: '1' }, { id: '2', user_id: '2' }, { id: '3', user_id: '3' }], exists = new Set(arr2.map(({ id }) => +id)), missing = arr1.filter(({ id }) => !exists.has(id)); console.log(missing); 

You can combine Array.filter() and Array.some() like this:

 const arr1 = [ {id: 1, user_id: 1}, {id: 2, user_id: 2}, {id: 3, user_id: 3}, {id: 4, user_id: 4}, ] const arr2 = [ {id: '1', user_id: '1'}, {id: '2', user_id: '2'}, {id: '3', user_id: '3'}, ] const newArray = arr1.filter(obj1 => !arr2.some(obj2 => obj1.id === +obj2.id)); console.log(newArray); 

When you are walking through an array yourself and checking if an element is not present, you can tell the outcome either when you find the element (then it is present, you can even break ), or when you walked through the entire array without finding it (then it is not present, has to be collected, but this can only happen at the end, after finishing the loop).

 const arr1 = [{id: 1, user_id: 1},{id: 2, user_id: 2},{id: 3, user_id: 3},{id: 4, user_id: 4}] const arr2 = [{id: '1', user_id: '1'},{id: '2', user_id: '2'},{id: '3', user_id: '3'}] const newArray = [] for (const x of arr1) { var found = false; // tracker variable for (const y of arr2) { if (x.id === +y.id) { // comparison became equality found = true; break; // if found, then it is found, inner loop can end here } } if(!found) { // element is stored when the inner loop has not found it newArray.push(x); } } console.log(newArray); 

That was the minimal fix, however as looking up values repeatedly with a loop is time consuming, you may rather want to do the Set approach from Nina Scholz's answer, or at least a "budget" solution with an object (or array) standing in for fast-lookup storage:

 const arr1 = [{id: 1, user_id: 1},{id: 2, user_id: 2},{id: 3, user_id: 3},{id: 4, user_id: 4}] const arr2 = [{id: '1', user_id: '1'},{id: '2', user_id: '2'},{id: '3', user_id: '3'}] const newArray = []; const lookup = {}; // if it is object... for (const y of arr2) { lookup[y.id]=true; // ... y.id remains string ... } for (const x of arr1) { if(!lookup[x.id]) { // ... numbers are stringified when used as property accessor newArray.push(x); } } console.log(newArray); 

You are adding the objects in the new array as soon as you find an object that is different from the one being evaluated. That's not what you want. You want to add the object only if ALL the objects are different.

The best way is by using a flag.

const arr1 = [...]

const arr2 = [...]

const newArray = []

for (const x of arr1) {
  found = false;
  for (const y of arr2) {
    if (x.id === +y.id) {       // IF FOUND ONE THAT IS EQUAL
      found = true;             // SET THE FLAG TO TRUE, AS YOU FOUND AN OBJECT THAT IS EQUAL
      break;
    }
  }
  if (!found) newArray.push(x); // ADD THE OBJECT ONLY AFTER CHECKING ALL THE OBJECTS FROM ARR2
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM