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?

4
  • 3
    id: 4 has banana ... Commented Dec 12, 2019 at 18:20
  • 2
    your expected result doesn't make sense based on the data you gave Commented Dec 12, 2019 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 Commented Dec 12, 2019 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)? Commented Dec 12, 2019 at 18:44

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

Comments

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!

8 Comments

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.
You are absolutely right @DillanWilding, thanks for pointing that out ;) I will update the example and give you credits.
@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 :)
yeah, I just reread it. The title is misleading because, like you said, it's the difference not the intersection. Thanks for checking though. :)
Just note that this algorithm is inefficient and will be much slower for large arrays o(n * m) instead of o(n + m)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.