Home > OS >  How to find index at similar items during the comparing of two arrays with object in JS
How to find index at similar items during the comparing of two arrays with object in JS

Time:11-01

I have 2 arrays with objects.

const users1 = [
    { name: 'John', age: 15, gender: 'M', city: 'London', country: 'UK' },
    { name: 'Jack', age: 20, gender: 'M', city: 'New York', country: 'USA' },
    { name: 'Jinny', age: 30, gender: 'F', city: 'London', country: 'UK' },
    { name: 'Key', age: 15, gender: 'M', city: 'Leeds', country: 'UK' },
  ],

const users2 = [
        { name: 'Jack', age: 20, gender: 'M', city: 'New York', country: 'USA' },
        { name: 'Key', age: 15, gender: 'M', city: 'Leeds', country: 'UK' },
      ],

I need to get index from users1 of that parts that are contains in users2.

As a result I should get [{1: true}, {3: true}]. I try in this way but it's not correct

const arr = user1.filter((item, index) => user2.map(i) => {
    if(i.id === item.id) return {index: true}
     return null;
    })

CodePudding user response:

First your array don't contains ids I filtered name for now.Also filter will not work here bcs if you use filter that will just filter your array and index will no longer be the same try following instead

const users1 = [
    { name: 'John', age: 15, gender: 'M', city: 'London', country: 'UK' },
    { name: 'Jack', age: 20, gender: 'M', city: 'New York', country: 'USA' },
    { name: 'Jinny', age: 30, gender: 'F', city: 'London', country: 'UK' },
    { name: 'Key', age: 15, gender: 'M', city: 'Leeds', country: 'UK' }
  ];

const users2 = [
        { name: 'Jack', age: 20, gender: 'M', city: 'New York', country: 'USA' },
        { name: 'Key', age: 15, gender: 'M', city: 'Leeds', country: 'UK' }
      ];

const arr = [];
users1.forEach((item, idx) =>{
    if(users2.some(u=> u.name == item.name)){
    arr.push({[idx]:true})
    }
    });
    console.log(arr)

CodePudding user response:

Just another approach - with Array.reduce()

const users1 = [
  { name: 'John', age: 15, gender: 'M', city: 'London', country: 'UK' },
  { name: 'Jack', age: 20, gender: 'M', city: 'New York', country: 'USA' },
  { name: 'Jinny', age: 30, gender: 'F', city: 'London', country: 'UK' },
  { name: 'Key', age: 15, gender: 'M', city: 'Leeds', country: 'UK' },
];

const users2 = [
  { name: 'Jack', age: 20, gender: 'M', city: 'New York', country: 'USA' },
  { name: 'Key', age: 15, gender: 'M', city: 'Leeds', country: 'UK' },
];

const arr = users1.
  reduce((previousValue, currentValue, index) => {
    // change here to find by id 
    if (users2.some(u2 => u2.name === currentValue.name) ){
      // map to whatever you want
      const valueToSave = {[index] : true};
      return [...previousValue, valueToSave];
    } else {
      return previousValue;
    }
  }, []);

console.log(arr);

CodePudding user response:

You could create a Set of all ids from users2 (a Set is somewhat like an array, but allows you to quickly check if a value is in it using .has() and it only stores unique values). Once you have the set, you can use .reduce() to create a new array, where you can use .concat() if the set has the id of the object from users1:

const users1 = [{ id: 1, name: 'John', age: 15, gender: 'M', city: 'London', country: 'UK' }, { id: 2, name: 'Jack', age: 20, gender: 'M', city: 'New York', country: 'USA' }, { id: 3, name: 'Jinny', age: 30, gender: 'F', city: 'London', country: 'UK' }, { id: 4, name: 'Key', age: 15, gender: 'M', city: 'Leeds', country: 'UK' }, ];
const users2 = [{ id: 2, name: 'Jack', age: 20, gender: 'M', city: 'New York', country: 'USA' }, { id: 4, name: 'Key', age: 15, gender: 'M', city: 'Leeds', country: 'UK' }, ];

const u2Ids = new Set(users2.map(user => user.id));
const res = users1.reduce((acc, obj, i) => u2Ids.has(obj.id) ? acc.concat({[i]: true}) : acc, []);
console.log(res);

When creating your objects you need to ensure you use computed property names when adding the index as a key {[i]: true} so that the value at i is used rather than the literal i name. The above can also be written with a for..of loop (by accessing Array.prototype.entries()), which is more efficient and (in my opinion) more readable:

const users1 = [{ id: 1, name: 'John', age: 15, gender: 'M', city: 'London', country: 'UK' }, { id: 2, name: 'Jack', age: 20, gender: 'M', city: 'New York', country: 'USA' }, { id: 3, name: 'Jinny', age: 30, gender: 'F', city: 'London', country: 'UK' }, { id: 4, name: 'Key', age: 15, gender: 'M', city: 'Leeds', country: 'UK' }, ];
const users2 = [{ id: 2, name: 'Jack', age: 20, gender: 'M', city: 'New York', country: 'USA' }, { id: 4, name: 'Key', age: 15, gender: 'M', city: 'Leeds', country: 'UK' }, ];

const res = [];
const u2Ids = new Set(users2.map(user => user.id));
for(const [i, obj] of users1.entries()) {
  if(u2Ids.has(obj.id))
    res.push({[i]: true});
}
console.log(res);

  • Related