【问题标题】:lodash - Count duplicate and then remove themlodash - 计算重复然后删除它们
【发布时间】:2017-12-23 21:56:19
【问题描述】:

我正在尝试使用 lodash 首先计算对象数组中有多少重复项,然后删除重复项(保留计数器)。

到目前为止,我的代码似乎可以工作,但我无法弄清楚如何将两者合并(抱歉,用 lodash 新建)。

这里有一些代码:

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();

我想清点,然后去掉但保持清点,这样最终的结果就基本告诉我订单中有多少产品,但保持不变,数量从1变为2。

我确实尝试过,但它不起作用:

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

这会给我这样的东西:

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}
]

有什么帮助吗?

谢谢

【问题讨论】:

标签: arrays object lodash


【解决方案1】:

您正在寻找一种在原生 JS 中广泛使用的 reduce 函数。这是一个完整的代码示例,可以在没有 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);

这是思考这个问题的好方法:

1) 您是否希望输出数组的大小相同(例如 1:1,每个输入都有一个输出)?然后你会想要使用地图。

2) 您希望输出数组的大小不同(通常更小)吗?然后你会想要使用reduce(或过滤器等)。

因为我们要删除重复项,所以您应该使用 #2。这至少会让你下次开始走上正确的道路!

【讨论】:

    【解决方案2】:

    我会使用 groupBy() 将具有相同 ID 的所有项目分组到单独的数组中,然后从每个单独的数组中只保留一个,将 qty 设置为其长度。

    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>

    编辑 更新以使其更短,并防止改变原始数组元素。

    【讨论】:

      【解决方案3】:

      一种更实用的方法可能是这种方法,它与公认的答案基本相同,但使用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)
      
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-04-10
        • 2017-06-15
        • 2022-01-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-08-07
        • 1970-01-01
        相关资源
        最近更新 更多