I have a collection like
const collection = [{url: '/string/'}, {url: '/string-2/'}]
and an array of string
const strings = ['/string/']
I'm trying to make the difference between the two in a way that the result is
const difference = [{url: '/string-2/'}]
I tried with lodash _.filter
const difference = _.filter(collection, obj => strings.every(url => url !== obj.self));
but it doesn't work. Tried with ._partition but it does return multiple arrays while I'd like to have just the collection without the object
4 Answers 4
Try differenceWith:
const collection = [{url: '/string/'}, {url: '/string-2/'}]
const strings = ['/string/']
result = _.differenceWith(collection, strings, (a, b) => a.url === b)
console.log(result) // [ { url: '/string-2/' } ]
Comments
You can do this without lodash, by using .filter() and check whether the current object's url is included in the strings array like so:
const collection = [{url: '/string/'}, {url: '/string-2/'}];
const strings = ['/string/'];
const difference = collection.filter(({url}) => strings.includes(url));
console.log(difference);
... or, if each url is unique, a more efficient way would be to create a Map where each key in the map is a url, which points to your object. Then .map() over your strings array like so:
const collection = [{url: '/string/'}, {url: '/string-2/'}];
const strings = ['/string/'];
const collection_map = new Map(collection.map(obj => [obj.url, obj]));
const difference = strings.map(str => collection_map.get(str));
console.log(difference);
With lodash, you can apply the same logic as above by using your _.filter() method with _.includes() like so:
const collection = [{url: '/string/'}, {url: '/string-2/'}];
const strings = ['/string/'];
const difference = _.filter(collection, obj => _.includes(strings, obj.url));
console.log(difference);
<script src="https://cdn.jsdelivr.net/lodash/4.16.4/lodash.min.js"></script>
Comments
You can do this with simple Array.prototype.includes() & Array.prototype.filter(), like this:
const collection = [{url: '/string/'}, {url: '/string-2/'}];
const strings = ['/string/'];
const difference = collection.filter(c => strings.includes(c.url) );
console.log(difference)
Comments
You can do it through vanilla JS. The necessary methods are filter() and some():
const collection = [{url: '/string/'}, {url: '/string-2/'}];
const strings = ['/string/'];
const difference = collection.filter(({url}) => strings.some(s=> url !== s));
console.log(res);