lodash - Count duplicate and then remove them

£可爱£侵袭症+ 提交于 2019-12-01 12:31:23

问题


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 seem to work, but I canìt figure out how to merge the two (sorry, new with lodash).

Here's some code:

var 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"},
]

// This finds the duplicates and removes them
result = _.uniqBy(array, 'id')

// this counts how many duplicates are in the array
count = _(result)
.groupBy('id')
.map((items, name) => ({ name, count: items.length }))
.value();

I would like to count, then remove but keep the count, so that the final result basically tells me how many products are in the order, but keeping the same together and changing the quantity from 1 to 2.

I did try with this, but it doesn't work:

result = _(result)
  .groupBy('id')
  .map((items, name) => ({ name, count: items.length }))
  .uniqBy(result, 'name')
  .value()

which will give me something like this:

result = [
{id: 1, name: "test", qty: 2},
{id: 2, name: "test 2", qty: 2},
{id: 3, name: "test 3", qty: 1},
{id: 4, name: "test 4", qty: 1}
]

Any help?

Thanks


回答1:


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.




回答2:


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!



来源:https://stackoverflow.com/questions/47956344/lodash-count-duplicate-and-then-remove-them

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!