【问题标题】:How can I de-dupe an array, and add additional properties to each object of the array based on its duplications如何对数组进行重复数据删除,并根据其重复项向数组的每个对象添加其他属性
【发布时间】:2021-06-16 10:30:11
【问题描述】:

假设我有一个如下所示的数组:

[
  { id 1, date: "1/1/2021", count: 2, oldCount: 1 },
  { id 1, date: "2/1/2021", count: 3, oldCount: 2 },
  { id 2, date: "1/1/2021", count: 2, oldCount: 1 },
  { id 2, date: "2/1/2021", count: 3, oldCount: 2 }
]

这里真正的关键是iddate 的组合。我希望最终结果如下所示:

[
  { id 1, "1/1/2021": 2, "2/1/2021": 3, "1/1/2021_old": 1, "2/1/2021_old": 2 },
  { id 2, "2/1/2021": 3, "2/1/2021": 3, "1/1/2021_old": 1, "2/1/2021_old": 2 }
]

我更喜欢使用 lodash。让我感到困惑的部分是要添加到数组中每个对象的附加属性。在我们的现实世界场景中,可能有数千条记录需要进行重复数据删除和映射,这是资源密集型的。

你可以看到逻辑。它按id 分组,并根据原始date 属性的值添加属性名称。

这是我想要的功能的一个无效示例:

arr = _.map(_.groupBy(data, "id"), objs => {              
  return _.assignWith({ /* I don't know the dates to set the property names */ }, ...objs)
});

我可以用嵌套循环来做到这一点。我正在寻找最佳性能选项和更少的代码行数。

【问题讨论】:

    标签: javascript lodash


    【解决方案1】:

    id 分组,映射组,然后映射每个组。映射组的对象时,使用具有各自值的[date][`${}_old`] 键创建一个新对象,然后使用带有数组扩展的_.merge() 将所有对象合并为一个对象。

    const arr = [{"id":1,"date":"1/1/2021","count":2,"oldCount":1},{"id":1,"date":"2/1/2021","count":3,"oldCount":2},{"id":2,"date":"1/1/2021","count":2,"oldCount":1},{"id":2,"date":"2/1/2021","count":3,"oldCount":2}]
    
    const result = _.map(
      _.groupBy(arr, 'id'),
      group => _.merge(
        {},
        ..._.map(group, ({ id, date, count, oldCount }) => ({ 
          id,
          [date]: count, 
          [`${date}_old`]: oldCount
        }))
      )
    )
    
    console.log(result)
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js" integrity="sha512-WFN04846sdKMIP5LKNphMaWzU7YpMyCU245etK3g/2ARYbPK9Ub18eG+ljU96qKRCWh+quCY7yefSmlkQw1ANQ==" crossorigin="anonymous"></script>

    与 lodash/fp 的想法相同,使用 _.flow() 生成更具可读性的函数,并使用 _.mergeAll() 合并所有项目 ig 一个组:

    const { flow, groupBy, map, mergeAll } = _
    
    const fn = flow(
      groupBy('id'),
      map(flow(
        map(({ id, date, count, oldCount }) => ({ 
          id,
          [date]: count, 
          [`${date}_old`]: oldCount 
        })),
        mergeAll
      ))
    )
    
    const arr = [{"id":1,"date":"1/1/2021","count":2,"oldCount":1},{"id":1,"date":"2/1/2021","count":3,"oldCount":2},{"id":2,"date":"1/1/2021","count":2,"oldCount":1},{"id":2,"date":"2/1/2021","count":3,"oldCount":2}]
    
    const result = fn(arr)
    
    console.log(result)
    <script src='https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)'></script>

    【讨论】:

      【解决方案2】:

      一个简单的Array.reduce 应该会产生您需要的东西——不需要库或外部依赖项并且仍然非常简短。

      const input = [
        { id: 1, date: "1/1/2021", count: 2, oldCount: 1 },
        { id: 1, date: "2/1/2021", count: 3, oldCount: 2 },
        { id: 2, date: "1/1/2021", count: 2, oldCount: 1 },
        { id: 2, date: "2/1/2021", count: 3, oldCount: 2 }
      ];
      
      const output = Object.values(input.reduce((a, c) => {
        a[c.id] = a[c.id] || {id: c.id};
        a[c.id][c.date] = c.count;
        a[c.id][`${c.date}_old`] = c.oldCount;
        return a;
      }, {}));
      
      console.log(output);

      【讨论】:

        猜你喜欢
        • 2018-11-14
        • 2016-08-31
        • 2017-12-16
        • 2012-05-17
        • 2016-11-08
        • 2020-06-29
        • 1970-01-01
        • 1970-01-01
        • 2018-03-06
        相关资源
        最近更新 更多