-1

I'm struggling to find a clean way to reduce or filter an array to contain no duplicate set values, when 2 of the values match. Here is an example of the data I am using. I am trying to remove any duplicates where title && genre both match.

[
  {
    "title": "american-hustle",
    "genre": "arts",
    "user": "penny"
  },
  {
    "title": "american-hustle",
    "genre": "comedy",
    "user": "brian"
  },
  {
    "title": "platoon",
    "genre": "war",
    "user": "tom"
  },
  {
    "title": "american-hustle",
    "genre": "arts",
    "user": "sarah"
  },
  {
    "title": "american-hustle",
    "genre": "arts",
    "user": "john"
  }
]

So in this case, the final two items should be removed, as both title && genre match that of an existing entry. Note, the second item should remain as american-hustle with a genre comedy, is still unique.

I've tried to find a similar question but I'm struggling to find one. Any help would be greatly appreciated.

unicorn_surprise
  • 951
  • 2
  • 21
  • 40

1 Answers1

4

Presented below is one possible way to achieve the desired objective.

Code Snippet

const myTransform = arr => (
  Object.values(
    arr.reduce(
      (acc, {title, genre, ...rest}) => (
        acc[`${title}${genre}`] ??= {title, genre, ...rest},
        acc
      ),
      {}
    )
  )
);
// explanation of code is below
/* transform array to remove dupes
const myTransform = arr => (
  Object.values(      // extract only the values of the below intermediate result-object
    arr.reduce(       // use ".reduce()" to iterate with "acc" as accumulator
      // de-structure the iterator to access title, genre, other props
      (acc, {title, genre, ...rest}) => (
        // conditionally assign value to 'acc' with key as combination of
        // title=genre and value as the original object's key-value pairs
        acc[`${title}${genre}`] ??= {title, genre, ...rest},
        // NOTE: Using "??=" ensures the first occurance of a dupe is retained
        // If one would use "=" instead, the last occurance shall be retained
        // always return "acc"
        acc
      ),
      {}        // initialize "acc" as an empty object
    )
  )             // implicit return of the object-values array
);
*/
const myArr = [
  {
    "title": "american-hustle",
    "genre": "arts",
    "user": "penny"
  },
  {
    "title": "american-hustle",
    "genre": "comedy",
    "user": "brian"
  },
  {
    "title": "platoon",
    "genre": "war",
    "user": "tom"
  },
  {
    "title": "american-hustle",
    "genre": "arts",
    "user": "sarah"
  },
  {
    "title": "american-hustle",
    "genre": "arts",
    "user": "john"
  }
];

console.log(
  'removed dupes using title-genre combination',
  myTransform(myArr)
);
.as-console-wrapper { max-height: 100% !important; top: 0 }

Explanation

Inline comments added to the snippet above.

jsN00b
  • 3,584
  • 2
  • 8
  • 21