2
let arr1 = [{ countryCode: "ITA", index: 2, name: "Italy"}, { countryCode: "NLD", index: 1, name: "Netherlands"}];

let arr2 = [{ countryCode: "NLD", index: 1, name: "Netherlands"}, { countryCode: "BEL", index: 3, name: "Belgium"}];

I want it to return the symmetric difference, so it should return:

[{ countryCode: "ITA", index: 2, name: "Italy"},  {countryCode: "BEL", index: 3, name: "Belgium"}]

How can I accomplish this in Javascript? I tried to do the following:

let difference = arr1
                 .filter(x => !arr2.includes(x))
                 .concat(arr2.filter(x => !arr1.includes(x))); 

But this doesn't seem to work for arrays with objects in them.

1
  • The reason is because equality checks on objects checks only the reference to the object, not each and every one of its key:value pairs. Commented Jan 21, 2021 at 21:19

3 Answers 3

2

You could take a Map and add or delete the item, if it is in the map.

const
    array1 = [{ countryCode: "ITA", index: 2, name: "Italy"}, { countryCode: "NLD", index: 1, name: "Netherlands" }],
    array2 = [{ countryCode: "NLD", index: 1, name: "Netherlands" }, { countryCode: "BEL", index: 3, name: "Belgium" }],
    map = new Map,
    cb = o => map.delete(o.countryCode) || map.set(o.countryCode, o);

array1.forEach(cb);
array2.forEach(cb);

console.log(Array.from(map.values()));

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

Comments

1

I'd collect one of the unique values in the objects (like countryCode) into an array of just those values, then you can use your original approach:

const arr1 = [{ countryCode: "ITA", index: 2, name: "Italy"}, { countryCode: "NLD", index: 1, name: "Netherlands"}];
const arr2 = [{ countryCode: "NLD", index: 1, name: "Netherlands"}, { countryCode: "BEL", index: 3, name: "Belgium"}];

const arr1Codes = arr1.map(a => a.countryCode);
const arr2Codes = arr2.map(a => a.countryCode);

const result = arr1
  .filter(a => !arr2Codes.includes(a.countryCode))
  .concat(arr2.filter(a => !arr1Codes.includes(a.countryCode)));
console.log(result);

Comments

1

You can first get the set of the unique country codes and then get the unique elements in each array using .filter:

const arr1 = [
  { countryCode: "ITA", index: 2, name: "Italy"}, 
  { countryCode: "NLD", index: 1, name: "Netherlands"}
];
const arr2 = [
  { countryCode: "NLD", index: 1, name: "Netherlands"}, 
  { countryCode: "BEL", index: 3, name: "Belgium"}
];

const arr = [...arr1, ...arr2];
const countryCodes = arr.map(e => e.countryCode);

const uniqueCountryCodes = new Set(
  countryCodes.filter(e => countryCodes.indexOf(e) === countryCodes.lastIndexOf(e))
);

const difference = arr.filter(x => uniqueCountryCodes.has(x.countryCode));

console.log(difference);

Comments

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.