I am trying to use lodash to first count how many duplicates are in an array of objects and the remove the duplicate (keeping the counter).
The code I have so far se
You're looking for a reduce function, which is widely available in native JS. Here's a full code sample that does the job without Lodash:
const inputArray = [
{id: 1, name: "test"},
{id: 2, name: "test 2"},
{id: 3, name: "test 3"},
{id: 4, name: "test 4"},
{id: 1, name: "test "},
{id: 2, name: "test 2"}
];
const uniqueArrayWithCounts = inputArray.reduce((accum, val) => {
const dupeIndex = accum.findIndex(arrayItem => arrayItem.id === val.id);
if (dupeIndex === -1) {
// Not found, so initialize.
accum.push({
qty: 1,
...val
});
} else {
// Found, so increment counter.
accum[dupeIndex].qty++;
}
return accum;
}, []);
console.log(uniqueArrayWithCounts);
Here's a good way to think about this:
1) Do you want the output array to be the same size (e.g. 1:1, every input has an output)? Then you're going to want to use map.
2) Do you want the output array to be a different size (usually smaller)? Then you're going to want to use reduce (or filter, etc).
Because we want to remove duplicates, that should lead you to use #2. That'll at least get you started going down the right path next time!
I would use groupBy()
to group all items with the same ID into separate arrays, then only keep one from each individual array, setting qty
to its length.
const array = [
{id: 1, name: "test"},
{id: 2, name: "test 2"},
{id: 3, name: "test 3"},
{id: 4, name: "test 4"},
{id: 1, name: "test "},
{id: 2, name: "test 2"}
];
const result = _(array).groupBy('id').values().map(
(group) => ({...group[0], qty: group.length})
);
console.log(result);
<script src="https://unpkg.com/lodash@4.17.4/lodash.js"></script>
Edit Updated to make it shorter, and prevent mutating the original array elements.
A more functional approach could be this one, that is basically the same logic than the accepted answer but using lodash/fp
const array = [
{ id: 1, name: 'test' },
{ id: 2, name: 'test 2' },
{ id: 3, name: 'test 3' },
{ id: 4, name: 'test 4' },
{ id: 1, name: 'test' },
{ id: 2, name: 'test 2' },
]
_.flow(
_.groupBy()('id'),
_.map(keys => ({
...(_.head(keys)),
qty: keys.length,
})),
_.tap(console.log)
)(array)