减少和分组对象数组

如何解决减少和分组对象数组

这是我的对象数组。我正在谷歌表格中编写一个自定义脚本来接收交易数据并将其分解为一个独特项目列表,其中订购的金额相加以创建更易于阅读的购买历史记录。

 products = [ 
      { id: 1,item: 'Beef',category: 'Meat',orderAmount: 5,caseSize: 1,unit: 'Lb',price: 50,supplier: 'Sysco' },{ id: 2,item: 'Chicken',orderAmount: 10,caseSize: 2,unit: 'Grams',price: 100,supplier: 'Findlay' },{ id: 3,item: 'Fish',category: 'Seafood',orderAmount: 15,caseSize: 3,price: 40,supplier: 'Deodato' },{ id: 1,// This is an example duplicate entry
        item: 'Beef',category: undefined,orderAmount: 100,supplier: 'Sysco' } 
    ]

我对如何将其分解为另一个对象感到有些困惑,其中删除了重复项,但将重复项的 orderAmounts 相加。

uniqueProducts = [ 
  { id: 1,orderAmount: 105,//this is the altered amount
    caseSize: 1,supplier: 'Deodato' }
]

我一直在阅读如何使用 map 和 reduce 函数,但我很难弄清楚如何使用如此大的对象来实现它们。

解决方法

您可以编写一个通用的 group 函数,该函数采用 grouper 函数来指定使项目重复的原因,并使用 update 函数指定重复项时如何更新结果被发现 -

function group(input,grouper,update) {
  function reducer(res,item) {
    const uniq = grouper(item)
    return res.has(uniq)
      ? res.set(uniq,update(res.get(uniq),item))
      : res.set(uniq,item)
  }
  return Array.from(input.reduce(reducer,new Map).values())
}

const products = 
  [{id:1,item:'Beef',category:'Meat',orderAmount:5,caseSize:1,unit:'Lb',price:50,supplier:'Sysco'},{id:2,item:'Chicken',orderAmount:10,caseSize:2,unit:'Grams',price:100,supplier:'Findlay'},{id:3,item:'Fish',category:'Seafood',orderAmount:15,caseSize:3,price:40,supplier:'Deodato'},{id:1,category:undefined,orderAmount:100,supplier:'Sysco'}]

const result =
  group
    ( products,item => item.id,(original,duplicate) =>
        ({ ...original,orderAmount: original.orderAmount + duplicate.orderAmount })
    )

console.log(result)
.as-console-wrapper { min-height: 100%; }

[
  {
    "id": 1,"item": "Beef","category": "Meat","orderAmount": 105,// <- grouped
    "caseSize": 1,"unit": "Lb","price": 50,"supplier": "Sysco"
  },{
    "id": 2,"item": "Chicken","orderAmount": 10,"caseSize": 2,"unit": "Grams","price": 100,"supplier": "Findlay"
  },{
    "id": 3,"item": "Fish","category": "Seafood","orderAmount": 15,"caseSize": 3,"price": 40,"supplier": "Deodato"
  }
]

上面我们看到 group 期望一个数组作为输入并返回一个数组作为输出。如果 group 接受任何 iterable 并返回一个可迭代对象,我们可以使它更有用。数组是可迭代的,因此它们仍然可以按预期工作,但其他可迭代对象也可以工作 -

function group(input,update) {
  const res = new Map
  for (const item of input) {
    const uniq = grouper(item)
    res.set
      ( uniq,res.has(uniq)
          ? update(res.get(uniq),item)
          : item
      )
  }
  return res.values()
}

function* products () {
  yield {id:1,supplier:'Sysco'}
  yield {id:2,supplier:'Findlay'}
  yield {id:3,supplier:'Deodato'}
  yield {id:1,supplier:'Sysco'}
}

const grouping =
  group
    ( products(),orderAmount: original.orderAmount + duplicate.orderAmount })
    )

for (const item of grouping)
  console.log(item)

注意输出是如何包裹在数组中的 -

{
  "id": 1,// <- grouped
  "caseSize": 1,"supplier": "Sysco"
}
{
  "id": 2,"supplier": "Findlay"
}
{
  "id": 3,"supplier": "Deodato"
}

要从任何可迭代对象中获取数组,可以使用 Array.from 函数 -

Array.from(grouping) // => [ ... ]
,

有更快的方法可以做到这一点,但一个好的起点是遍历匹配结果,如果该项目不在列表中,则附加该项目。请务必复制对象,否则您将更改原始值。

uniqueProducts  = products.reduce((result,item)=> {

   var hit = 0;
   for(var idx=0; idx<result.length; idx++) {
      if (result[idx].id == item.id) {
          hit += 1;
          result[idx].orderAmount += item.orderAmount;
          idx = result.length;
      }
   }

   if (hit === 0) {
       result.push(Object.assign({},item));
   }
   return result;

},[]);

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?