Home > database >  Compare one array with a nested array and push value into a new array in Javascript
Compare one array with a nested array and push value into a new array in Javascript

Time:07-24

I have 2 arrays

const arrayOne = [
 {id: '110'},
 {id: '202'},
 {id: '259'}
];

const arrayTwo = [
 {data: [{value: 'Alpha', id: '001'}]},
 {data: [{value: 'Bravo', id: '202'}]},
 {data: [{value: 'Charlie', id: '752'}]},
 {data: [{value: 'Delta', id: '202'}, {value: 'Sierra', id: '110'}]},
 {data: [{value: 'Echo', id: '937'}]}
];

I need to create a new array comparing arrayOne[idx].id with arrayTwo[idx].data[idx2].id

Upon match, I need to create an array pushing value or the entire matching object into a new array.

In this example, desired result should be newArray = ['Bravo', 'Delta', 'Sierra']

What I have tried:

let result = arrayOne.map(el => {
  let found = arrayTwo.find(f => f.data.at(0)?.id == el.id)?.data.at(0)?.value;
  return { id: el.id, value: found ?? null};
});

const result = arrayTwo
  .map(obj => obj.data[0])
  .map(obj => (arrayOne.find(v => v.id === obj.id) && obj.value))

arrayOne.map(item => ({
   ...item,
   result: arrayTwo.filter(itemTwo => item.data.map(x => x.id).includes(itemTwo.id))
}));

CodePudding user response:

You're only checking the first index:

let found = arrayTwo.find(f => f.data.at(0)?.id == el.id)?.data.at(0)?.value;

If the first index doesn't match, but further indicies do, they won't be found.

I think you're overcomplicating things a bit. Make a Set of the IDs to find, then just iterate over each .data array, pushing the object to the output array if the ID matches.

const arrayOne=[{id:"110"},{id:"202"},{id:"259"}],arrayTwo=[{data:[{value:"Alpha",id:"001"}]},{data:[{value:"Bravo",id:"202"}]},{data:[{value:"Charlie",id:"752"}]},{data:[{value:"Delta",id:"202"},{value:"Sierra",id:"110"}]},{data:[{value:"Echo",id:"937"}]}];

const idsToFind = new Set(arrayOne.map(({ id }) => id));
const output = [];
for (const { data } of arrayTwo) {
  for (const obj of data) {
    if (idsToFind.has(obj.id)) output.push(obj.value);
  }
}
console.log(output);

If you prefer a less imperative approach:

const arrayOne=[{id:"110"},{id:"202"},{id:"259"}],arrayTwo=[{data:[{value:"Alpha",id:"001"}]},{data:[{value:"Bravo",id:"202"}]},{data:[{value:"Charlie",id:"752"}]},{data:[{value:"Delta",id:"202"},{value:"Sierra",id:"110"}]},{data:[{value:"Echo",id:"937"}]}];

const idsToFind = new Set(arrayOne.map(({ id }) => id));
const output = arrayTwo
  .flatMap(({ data }) => data.filter(
    obj => idsToFind.has(obj.id)
  ))
  .map(obj => obj.value);
console.log(output);

CodePudding user response:

For this, instead of mapping into the object inside the array in data, we can map to the array itself giving us an array of arrays and then use flat() to get just one array of {value, id} objects. Then we map over that array and look for the id.

Note that this solution will push duplicate values. To avoid duplicates, we can either make a Set and spread it into a new array.

You can also avoid duplicates by instead adding a condition to the forEach that tries to find() the value in the output array.

const arrayOne = [
 {id: '110'},
 {id: '202'},
 {id: '259'}
];

const arrayTwo = [
 {data: [{value: 'Alpha',id: '001'}]},
 {data: [{value: 'Bravo',id: '202'}]}, 
 {data: [{value: 'Charlie',id: '777'}, {value: 'Sierra', id: '259'}]},
 {data: [{value: 'Delta',id: '202'}, {value: 'Sierra', id: '259'}]}
];

const output = [];

arrayTwo
  .map(obj => obj.data)
  .flat()
  .forEach(obj => (arrayOne.find(v => v.id === obj.id) && output.push(obj.value)))
  
console.log('Output:', output)

const uniqueOutput = [...new Set(output)]
console.log('Unique Output:', uniqueOutput)

  • Related