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.
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.