My collection looks like this.
var list = [{id:'12345', sequence:null}, {id:'12346', sequence:null}, {id:'12347', sequence:null}, {id:'12348', sequence:1}, {id:'12348', sequence:2}, {id:'12349', sequence:1}, {id:'12349', sequence:1}];
I am trying to get a unique list so that object with same id AND sequence will only return one of the objects (we have 2 here- {id:'12349', sequence:1})
my code
var uniqueList = _.uniq(list, function(obj) {
return obj.id && obj.sequence;
});
can we use lodash uniq like this? what is the approach to fix this issue?
You can use uniqBy() to compute the criterion by which the list is generated wherein the iteratee callback returns the joined value of id
and sequence
of each item of the colection. The solution below works great when you only want to have specific properties to be the criterion of uniqueness especially when each object in your collection may not only have the id
and sequence
properties.
var result = _.uniqBy(list, v => [v.id, v.sequence].join());
var list = [{
id: '12345',
sequence: null
}, {
id: '12346',
sequence: null
}, {
id: '12347',
sequence: null
}, {
id: '12348',
sequence: 1
}, {
id: '12348',
sequence: 2
}, {
id: '12349',
sequence: 1
}, {
id: '12349',
sequence: 1
}, {
id: '123490',
sequence: 1,
extra: 1
}, {
id: '123490',
sequence: 1,
extra: 2
}];
var result = _(list)
.uniqBy(v => [v.id, v.sequence].join())
.value();
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.12.0/lodash.js"></script>
Alternatively, if you have properties that contains non-primitive values (objects or arrays) to be used as the criterion then you can still use the solution above but instead joining the array of values, you have to use JSON.stringify()
var result = _.uniqBy(list, v => JSON.stringify([v.id, v.sequence]));
var list = [{
id: '12345',
sequence: null
}, {
id: '12346',
sequence: null
}, {
id: '12347',
sequence: null
}, {
id: '12348',
sequence: 1
}, {
id: '12348',
sequence: 2
}, {
id: '12349',
sequence: 1
}, {
id: '12349',
sequence: 1
}, {
id: '123490',
sequence: 1,
extra: 1
}, {
id: '123490',
sequence: 1,
extra: 2
}];
var result = _.uniqBy(list, v => JSON.stringify([v.id, v.sequence]));
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.12.0/lodash.js"></script>
UPDATE:
For the lodash3 solution, for properties with primitive values, you can still use the pattern in the first solution using uniq().
var result = _.uniq(list, v => [v.id, v.sequence].join());
var list = [{
id: '12345',
sequence: null
}, {
id: '12346',
sequence: null
}, {
id: '12347',
sequence: null
}, {
id: '12348',
sequence: 1
}, {
id: '12348',
sequence: 2
}, {
id: '12349',
sequence: 1
}, {
id: '12349',
sequence: 1
}, {
id: '123490',
sequence: 1,
extra: 1
}, {
id: '123490',
sequence: 1,
extra: 2
}];
var result = _.uniq(list, v => [v.id, v.sequence].join());
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.js"></script>
And for the non-primitive properties, you can still use the 2nd example above with uniq()
var result = _.uniq(list, v => JSON.stringify([v.id, v.sequence]));
var list = [{
id: '12345',
sequence: null
}, {
id: '12346',
sequence: null
}, {
id: '12347',
sequence: null
}, {
id: '12348',
sequence: 1
}, {
id: '12348',
sequence: 2
}, {
id: '12349',
sequence: 1
}, {
id: '12349',
sequence: 1
}, {
id: '123490',
sequence: 1,
extra: 1
}, {
id: '123490',
sequence: 1,
extra: 2
}];
var result = _.uniq(list, v => JSON.stringify([v.id, v.sequence]));
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.js"></script>
You may use uniqWith
This method is like _.uniq except that it accepts comparator which is invoked to compare elements of array. The comparator is invoked with two arguments: (arrVal, othVal).
and isEqual
Performs a deep comparison between two values to determine if they are equivalent.
_.uniqWith(list, _.isEqual);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With