Javascript 按类型对集合的值求和,并将其分配给复制对象上的新属性

Javascript 按类型对集合的值求和,并将其分配给复制对象上的新属性,javascript,functional-programming,Javascript,Functional Programming,我试图对集合中的值求和,并将它们添加到每个对象的新属性中 var collection = [ {prop:'title',quan:2}, {prop:'body',quan:3}, {prop:'title',quan:2}, {prop:'title',quan:4}, ] /* desired result [ {prop:'title', quan:2, stock:8}, {prop:'body', quan:3, stock:3}, {prop:'title

我试图对集合中的值求和,并将它们添加到每个对象的新属性中

var collection = [
 {prop:'title',quan:2},
 {prop:'body',quan:3},
 {prop:'title',quan:2},
 {prop:'title',quan:4},
]

/* desired result
 [
  {prop:'title', quan:2, stock:8},
  {prop:'body', quan:3, stock:3},
  {prop:'title', quan:2, stock:8},
  {prop:'title', quan:4, stock:8},
 ]
*/
我尝试过许多不同的方法,但都没有成功。我试图以一种实用的方式来做这件事

这是我目前的困境,我很确定这是最简洁的方式

// group the props using key
var result = _.groupBy(collection,'prop');
哪个输出

{
  title:[
   {prop:'title',quan:2},{prop:'title',quan:2},{prop:'title',quan:4}
  ], 
  body:[
   {prop:'body':quan:3}
  ]
}
因此,让我们减少我们创建的阵列

var obj = {};
_.forEach(result,function(value,key){    
    obj[key] = _.reduce(value,function(acc,val){
      return acc.quan + val.quan
    });       
});
但是上面的这个部分不起作用了

当我有工作,我应该能够映射回我的最终收集

我们知道总数,将它们映射到集合

var final = _.map(collection,function(value){
  return {
    type:value.prop,
    val:value.quan,
    stock:obj[value.prop]
  }
});

首先,您必须获取sum对象,然后将sum分配给相应的对象。像这样:

功能库存(arr){
//使用lodach:var sum=\减少(arr,…)
var sum=arr.reduce(函数(s,o){//获取sum对象(散列)
s[o.prop]=(s[o.prop]| | | 0)+o.quan;//如果总和已包含此对象的项目porp,则将其添加到其quan中,否则添加0
返回s;
}, {});
//使用lodash:u.forEach(arr,…);
arr.forEach(函数(o){//将和分配给对象
o、 stock=sum[o.prop];//此对象的stock是它的prop与sum对象的哈希
});
}
变量集合=[
{prop:'title',quan:2},
{prop:'body',quan:3},
{prop:'title',quan:2},
{prop:'title',quan:4},
]
库存(收集);

控制台日志(收集)首先您必须获取sum对象,然后将sum分配给相应的对象。像这样:

功能库存(arr){
//使用lodach:var sum=\减少(arr,…)
var sum=arr.reduce(函数(s,o){//获取sum对象(散列)
s[o.prop]=(s[o.prop]| | | 0)+o.quan;//如果总和已包含此对象的项目porp,则将其添加到其quan中,否则添加0
返回s;
}, {});
//使用lodash:u.forEach(arr,…);
arr.forEach(函数(o){//将和分配给对象
o、 stock=sum[o.prop];//此对象的stock是它的prop与sum对象的哈希
});
}
变量集合=[
{prop:'title',quan:2},
{prop:'body',quan:3},
{prop:'title',quan:2},
{prop:'title',quan:4},
]
库存(收集);

控制台日志(收集)我更喜欢这个解决方案,因为它抽象了排序规则,但允许您使用高阶函数控制如何对项目进行排序

请注意,我们在collateBy函数中根本不讨论数据的种类或结构——这使我们的函数保持通用性,并允许它处理任何形状的数据

collateBy
采用分组函数
f
和归约函数
g
以及任何类型数据的同质数组

//校对人::(a->b)->(c,a)->c)->[a]->Map(b:c)
常数collateBy=f=>g=>xs=>{
返回x.reduce((m,x)=>{
设v=f(x)
返回m.set(v,g(m.get(v),x))
},新映射())
}
const collateByProp=collateBy(x=>x.prop)
const assignTotalStock=xs=>{
让股票=collateByProp((acc=0,{quan})=>acc+quan)(xs)
返回xs.map(({prop,quan})=>
({prop,quan,stock:stocks.get(prop)})
}
变量集合=[
{prop:'title',quan:2},
{prop:'body',quan:3},
{prop:'title',quan:2},
{prop:'title',quan:4},
]
控制台日志(assignTotalStock(集合))
//[{prop:'title',quan:2,stock:8},
//{道具:'身体',拳:3,股票:3},
//{prop:'title',quan:2,stock:8},
//{道具:'头衔',全:4,股票:8}]

我更喜欢这个解决方案,因为它抽象了排序规则,但允许您使用高阶函数控制项目的排序方式

请注意,我们在collateBy函数中根本不讨论数据的种类或结构——这使我们的函数保持通用性,并允许它处理任何形状的数据

collateBy
采用分组函数
f
和归约函数
g
以及任何类型数据的同质数组

//校对人::(a->b)->(c,a)->c)->[a]->Map(b:c)
常数collateBy=f=>g=>xs=>{
返回x.reduce((m,x)=>{
设v=f(x)
返回m.set(v,g(m.get(v),x))
},新映射())
}
const collateByProp=collateBy(x=>x.prop)
const assignTotalStock=xs=>{
让股票=collateByProp((acc=0,{quan})=>acc+quan)(xs)
返回xs.map(({prop,quan})=>
({prop,quan,stock:stocks.get(prop)})
}
变量集合=[
{prop:'title',quan:2},
{prop:'body',quan:3},
{prop:'title',quan:2},
{prop:'title',quan:4},
]
控制台日志(assignTotalStock(集合))
//[{prop:'title',quan:2,stock:8},
//{道具:'身体',拳:3,股票:3},
//{prop:'title',quan:2,stock:8},
//{道具:'头衔',全:4,股票:8}]

我不久前就接近了,但我突然偏离了方向,谢谢。回答得好!我想不出比这更简单的方法了it@ibrahimmahrir啊,我现在明白了。很抱歉。为了避免混淆,我将删除我以前的评论。我在前一段时间很接近那个评论,但后来偏离了方向,谢谢。回答得好!我想不出比这更简单的方法了it@ibrahimmahrir啊,我现在明白了。很抱歉。为了避免混淆,我将删除我以前的评论。可能重复“我正试图以一种功能性的方式来做这件事。”——那么你不应该改变你的输入,fwiw@noamik我读了一些书,因为你提到数据不应该变异,现在对函数编程有了更好的理解,虽然你的回答仍然有点超出我的理解。可能重复“我正试图以一种功能性的方式来做这件事”——那么你不应该改变你的输入,fwiw@noamik我读了一些书,因为你提到数据不应该变异,现在对函数编程有了更好的理解,虽然你的回答还是有点超出我的理解。