0

I have two arrays like so

data = [{id: 1, name: apple},
{id: 2, name: mango},
{id: 3, name: grapes},
{id: 4, name: banana}]

data2 =[{id: 1, name: apple},
{id: 3, name grapes}]

My Expected result would be:

[{ id: 2, name: mango}, 
{id:4, name: banana}]

My code is

let finalData =[];
data.forEach(result => {
 data2.find(datum => {
  if(datum['id'] === result['id]{
    finalData.push(result);
   }
 })
})

I am getting wrong result. What is the simplest code or library that I can use?

Jacob
  • 77,566
  • 24
  • 149
  • 228
aJaysanity
  • 165
  • 1
  • 5
  • 13
  • 3
    `id: 4` has banana ... – Nina Scholz Dec 12 '19 at 18:20
  • 2
    your expected result doesn't make sense based on the data you gave – JAAulde Dec 12 '19 at 18:21
  • Your example is not an intersection, and it's not clear what do you expect to happen if data2 has elements that are not present in data1 – arieljuod Dec 12 '19 at 18:31
  • Did you mean to have an expected result of `[{ id: 1, name: 'apple' }, {id: 3, name: 'grapes' }]` (an intersection) or `[{ id: 2, name: 'mango' }, { id: 4, name: 'banana' }]` (a difference)? – Jacob Dec 12 '19 at 18:44

2 Answers2

3

Your sample data doesn't make sense, but assuming you mean that all data items that have matching IDs also have matching names and also assuming you want a set of all items where the IDs are the same in the two sets of data, you could use a Set to keep track of which IDs are present in one array then filter the second array by those that have their IDs in the set:

const idsInFirst = new Set(data.map(d => d.id));
const intersection = data2.filter(d => idsInFirst.has(d.id));

The reason why an intermediate Set structure is used is because it allows O(1) lookups after a one-time scan, which is more efficient than repeatedly scanning the first array over and over.

If you meant to say you wanted a difference between data sets (items excluded from data that are in data2), you'd want to negate/inverse things a bit:

const idsToExclude = new Set(data2.map(d => d.id));
const difference = data.filter(d => !idsToExclude.has(d.id));

Edit

After your clarifying edit, it's that second block of code that you'll want.

Jacob
  • 77,566
  • 24
  • 149
  • 228
2

I would say a good way to do that is filtering your longest array using a function that will validate if the object id is present in both arrays. Check this example:

const data = [
  {id: 1, name: 'apple'},
  {id: 2, name: 'mango'},
  {id: 3, name: 'grapes'},
  {id: 4, name: 'banana'}
]

const data2 =[
  {id: 1, name: 'apple' },
  {id: 3, name: 'grapes' }
]

const longest  = data.length > data2.length ? data : data2;
const shortest = data.length <= data2.length ? data : data2;

const finalData = longest.filter( obj => !shortest.find( o => o.id === obj.id ) )

console.log(finalData)

Good luck!

Davo
  • 966
  • 7
  • 15
  • 2
    If it's an intersection, wouldn't it be more efficient to filter shortest rather than longest? No need to check any element that couldn't be in the smaller array unless filter is more performant/efficient than find is. – Dillan Wilding Dec 12 '19 at 18:32
  • You are absolutely right @DillanWilding, thanks for pointing that out ;) I will update the example and give you credits. – Davo Dec 12 '19 at 18:33
  • @DillanWilding I was writing the code and I realized that the actual thing being looked for is the ones which are not in the intersection :) – Davo Dec 12 '19 at 18:44
  • 1
    yeah, I just reread it. The title is misleading because, like you said, it's the difference not the intersection. Thanks for checking though. :) – Dillan Wilding Dec 12 '19 at 18:51
  • Just note that this algorithm is inefficient and will be much slower for large arrays `o(n * m)` instead of `o(n + m)` – Jacob Dec 12 '19 at 18:52
  • I agree @Jacob, needs to be used according to the context ;) – Davo Dec 12 '19 at 18:56
  • I tried it on large array it is slower than expected. – aJaysanity Dec 12 '19 at 19:06
  • Check this out guys, someone did a few experiments about it https://stackoverflow.com/a/39010462/1819588. It looks like you need to keep in mind which operations you will execute on the resulting array @aJaysanity Thanks to everyone for sharing your knowledge! – Davo Dec 12 '19 at 19:10