Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Merge two map objects and return custom objects javascript

I have two arrays

let a1 = [{id: 1, name: "terror"}, {id: 2, name: "comics"}, {id: 3, name: "suspense"}]
let a2 = [{id: 1, name: "terror"}, {id: 3, name: "suspense"}]

I need to compare these arrays against each other and come out with something like this: [{id: 1, name: "terror", selected: true}, {id: 2, name: "comics", selected: false}, {id: 3, name: "suspense", selected: true}]

I tried using filter below, but it didn't work, what should I do?

a2.filter(data => {
  return a1.find(value => {
    let x = data.id === value.id ? {
      id: value.id,
      text: value.name,
      selected: true
    } : {
      id: data.id,
      text: data.name,
      selected: false
    }
  })
})
like image 625
Edoardo Lopez Avatar asked Sep 14 '26 20:09

Edoardo Lopez


1 Answers

You shouldn't use filter because you need an output array that has the same number of items you started with - use map instead, to create a new array which has the same number of elements as the original array, only transformed.

Since it looks like a2 doesn't have any new information, and is only useful by showing the existence or abscence of some objects, a method with low complexity would be to map a2 to a Set of ids, and then generate the new objects by iterating over a1 and checking whether their ids are in the Set:

let a1 = [{id: 1, name: "terror"}, {id: 2, name: "comics"}, {id: 3, name: "suspense"}]
let a2 = [{id: 1, name: "terror"}, {id: 3, name: "suspense"}]
const a2IDs = new Set(a2.map(({ id }) => id));
const output = a1.map((item) => ({ ...item, selected: a2IDs.has(item.id) }));
console.log(output);

It would be possible to fix up your code so that it works, changing .filter to .map and using .find as you are, but it'll have greater complexity because it'll have to iterate over items in a2 each time (Set lookups by comparison are O(1)).

like image 154
CertainPerformance Avatar answered Sep 16 '26 08:09

CertainPerformance