【问题标题】:how to return new array by using array.reduce如何使用 array.reduce 返回新数组
【发布时间】:2022-06-14 17:54:16
【问题描述】:

我想使用reduce返回新数组。例如,

const product = [
  { color: 'orange', type: 'hat', count: 1 },
  { color: 'orange', type: 'hat', count: 1 },
  { color: 'orange', type: 'shoes', count: 1 },
  { color: 'blue', type: 'food', count: 1 },
];

产品列表需要像下面这样,因为有两个“帽子”,因此计数应该是 2,并且应该删除一个 { color: 'orange', type: 'hat', count: 1 }。

const result = product.reduce((acc, curr) => {
// I want to make new array like
// const product = [
//  { color: 'orange', type: 'hat', count: 2 },
//  { color: 'orange', type: 'shoes', count: 1 },
//  { color: 'blue', type: 'food', count: 1 },
//];
 return acc
}

谢谢!

【问题讨论】:

标签: javascript arrays find lookup reduce


【解决方案1】:

我会这样做:

  • 先查找产品是否已经添加到curr数组中
  • 如果是,增加count
  • 否则,将新产品推送到数组中

注意:我使用了Spread operator 来制作对象的深层副本,而不是将当前对象推入数组。

这个结果通过不修改products数组而创建一个全新的数组

const product = [
  { color: 'orange', type: 'hat', count: 1 },
  { color: 'orange', type: 'hat', count: 1 },
  { color: 'orange', type: 'shoes', count: 1 },
  { color: 'blue', type: 'food', count: 1 },
];

const result = product.reduce((acc, curr) => {
 if(!acc) return [...curr]
 
 const exist = acc.find(x => x.type === curr.type && x.color === curr.color)
 exist ? exist.count += 1 : acc.push({...curr})
 return acc
}, [])

console.log(result)

【讨论】:

    【解决方案2】:

    你可以试试

    const product = [
      { color: 'orange', type: 'hat', count: 1 },
      { color: 'orange', type: 'hat', count: 1 },
      { color: 'orange', type: 'shoes', count: 1 },
      { color: 'blue', type: 'food', count: 1 },
    ];
    
    const result = product.reduce((res, obj) => {
      let exist = res.find(o => o.color === obj.color && o.type === obj.type)
      if (exist) {
        exist.count += obj.count
      } else {
        res = [...res, {...obj}]
      }
      return [...res]
    }, [])
    console.log(result)
    console.log(product)

    更新编辑yassine-el-bouchaibi的建议

    【讨论】:

    • 这个答案很危险,因为您正在修改原始对象上的count。如果 OP 想要在之后重新使用产品中的对象,这可能会产生意想不到的行为,因为他们不知道某些内部对象已被静音。这是一个不好的做法。最好制作一个副本,而不是在存在时重新归因 count
    【解决方案3】:

    从上面的评论...

    该任务也可以描述为分组、合并和聚合。这是一项非常常见的任务,可以通过通用实现但可自定义的减速器功能来解决...请参阅..."How to group and merge array entries and to sum-up values on multiple common (but not all) keys?"

    ...证明...

    function groupMergeAndAggregateGenerically(collector, item) {
      const {
        createKey, createMerger, aggregate,
        lookup, result = [],
      } = collector;
    
      const key = createKey(item);
      let merger = lookup.get(key) ?? null;
    
      if (merger === null) {
        merger = createMerger(item);
    
        lookup.set(key, merger);
        result.push(merger);
      }
      aggregate(merger, item);
    
      return collector;
    }
    
    const productData = [
      { color: 'orange', type: 'hat', count: 1 },
      { color: 'orange', type: 'hat', count: 1 },
      { color: 'orange', type: 'shoes', count: 1 },
      { color: 'blue', type: 'food', count: 1 },
    ];
    const { result: mergedData } = productData
      .reduce(groupMergeAndAggregateGenerically, {
        createKey: ({ color, type }) => [color, type].join('_'),
        createMerger: ({ color, type }) => ({ color, type, count: 0 }),
        aggregate: (merger, { count }) => merger.count += count,
        lookup: new Map,
        result: [],      
      });
    
    console.log({ mergedData, productData });
    .as-console-wrapper { min-height: 100%!important; top: 0; }

    【讨论】:

      猜你喜欢
      • 2022-11-07
      • 1970-01-01
      • 1970-01-01
      • 2020-09-06
      • 2017-08-28
      • 2022-01-15
      • 2016-07-23
      • 2020-09-28
      • 2012-08-30
      相关资源
      最近更新 更多