How about with some es6
magic?
obj.arr = obj.arr.filter((value, index, self) => index === self.findIndex((t) => ( t.place === value.place && t.name === value.name )) )
A more generic solution would be:
const uniqueArray = obj.arr.filter((value, index) => { const _value = JSON.stringify(value); return index === obj.arr.findIndex(obj => { return JSON.stringify(obj) === _value; }); });
Using the above property strategy instead of JSON.stringify
:
const isPropValuesEqual = (subject, target, propNames) => propNames.every(propName => subject[propName] === target[propName]); const getUniqueItemsByProperties = (items, propNames) => items.filter((item, index, array) => index === array.findIndex(foundItem => isPropValuesEqual(foundItem, item, propNames)) );
You can add a wrapper if you want the propNames
property to be either an array or a value:
const getUniqueItemsByProperties = (items, propNames) => { const propNamesArray = Array.from(propNames); return items.filter((item, index, array) => index === array.findIndex(foundItem => isPropValuesEqual(foundItem, item, propNamesArray)) ); };
allowing both getUniqueItemsByProperties('a')
and getUniqueItemsByProperties(['a']);
Explanation
- Start by understanding the two methods used:
- Next take your idea of what makes your two objects equal and keep that in mind.
- We can detect something as a duplicate, if it satisfies the criterion that we have just thought of, but it’s position is not at the first instance of an object with the criterion.
- Therefore we can use the above criterion to determine if something is a duplicate.