Skip to content

javascript Set with objects

When merging array of strings, I can use Set and ES6 to remove duplicates like so:

const a = ["hello", "hi", "yo"]
const b = ["alo", "hi"]
const remove_hi = [
  ...new Set([
    ...a,
    ...b,
  ]),
]

But how do I compare and remove objects? Say I have this:

const a = [
  {id: "asd", name: "Hi"},
  {id: "fgh", name: "Hello"},
  {id: "123", name: "Hi"}
]
const b = [
  {id: "jkl", name: "Yo"},
  {id: "123", name: "Hi"}
]
// This will not work. It will have a duplicate of {id: "123", name: "Hi"}
const remove_hi = [
  ...new Set([
    ...a,
    ...b,
  ]),
]

How do I remove {id: "123", name: "Hi"} from a combined array with Set?

Answer

Use a Map to deduplicate by the key name:

const uniqueBy = (array, key) => [
  ...new Map(
    array.map(o => [key(o), o])
  ).values()
];

const a = [
  {id: "asd", name: "Hi"},
  {id: "fgh", name: "Hello"},
  {id: "123", name: "Hi"}
]
const b = [
  {id: "jkl", name: "Yo"},
  {id: "123", name: "Hi"}
]
const remove_hi = uniqueBy([...a, ...b], o => o.name);

console.log(remove_hi);

Note that deduplicating only by name will remove both {id: "asd", name: "Hi"} and {id: "123", name: "Hi"} since they’d be considered duplicates of the last {id: "123", name: "Hi"} in the array when keying by name.

Replace o.name with whatever key you want to deduplicate by.