代码之家  ›  专栏  ›  技术社区  ›  sefirosu

JS reduce列表基于它的一个属性

  •  1
  • sefirosu  · 技术社区  · 7 年前

    我正在用react js编写一个方法,假设我有如下列表。

    const itemList = [
        {
            "id": 3295042,
            "tillPoint": "A",
            "date": "23/01/2019",
            "AnnaIncome": 100,
            "PeterIncome": 50,
            "KenIncome": 100,
            "freeCash": 30
        },
        {
            "id": 3295042,
            "tillPoint": "B",
            "date": "23/01/2019",
            "AnnaIncome": 300,
            "PeterIncome": 200,
            "KenIncome": 100,
            "freeCash": 50
        },
        {
            "id": 3295042,
            "tillPoint": "A",
            "date": "22/01/2019",
            "AnnaIncome": 120,
            "PeterIncome": 120,
            "KenIncome": 30,
            "freeCash": 50
        },
        {
            "id": 3295042,
            "tillPoint": "B",
            "date": "22/01/2019",
            "AnnaIncome": 100,
            "PeterIncome": 150,
            "KenIncome": 50,
            "freeCash": 60
        },
    ] 
    

    .reduce 为了使列表仅按日期属性包含较少的项。 例如,在上面的列表中,实际上只有两个日期:2019年1月22日和2019年1月23日。 我希望按每个对象的日期缩小列表的大小。因此,每个人的收入将以自己的名义加起来。 最终,列表将变成只有2个对象。并且在新列表中删除了某些属性 e、 g下面的“id”和“tillpoint”被删除,其余属性加在一起:

    let itemList = [
        {
            "date": "23/01/2019",
            "AnnaIncome": 300,
            "PeterIncome": 250,
            "KenIncome": 200,
            "freeCash": 80
        },
        {
            "date": "22/01/2019",
            "AnnaIncome": 220,
            "PeterIncome": 280,
            "KenIncome": 80,
            "freeCash": 110
        }
    ]
    

    我在这里尝试的是下面的内容,但它不起作用。

    itemList.reduce((a, b) => ({ date: a.AnnaIncome + b.AnnaIncome, a.PeterIncome + b.PeterIncome, a.KenIncome + b.KenIncome, a.freeCash + b.freeCash }));
    
    3 回复  |  直到 7 年前
        1
  •  2
  •   Jonas Wilms    7 年前

    您必须按日期分组,这可以使用哈希表轻松完成:

     const byDate = new Map;
    
     for(const { date, id, tillPoint, ...rest } of itemList) {
       if(byDate.has(date)) {
         const dupe = byDate.get(date);
         for(const [k, v] of Object.entries(rest))
           dupe[k] += v;
       } else {
         byDate.set(date, { date, ...rest });
       }
    }
    
    const result = [...byDate.values()];
    

    当然,您可以轻松地将添加内容硬编码为 dupe.something += rest.something

        2
  •  2
  •   Code Maniac    7 年前

    你可以用 reduce spread 操作人员

    所以这里我要做的是,我获取你想要直接添加到输出中的动态属性,而不需要任何操作 ...rest

    然后我检查数据键是否已经存在,然后添加 加 freeCash 现有价值。如果没有,我们将创建一个带有日期和相应值的新键。

    const itemList = [{"id":3295042,"tillPoint":"A","date":"23/01/2019","AnnaIncome":100,"PeterIncome":50,"KenIncom":100,"freeCash":30},{"id":3295042,"tillPoint":"B","date":"23/01/2019","AnnaIncome":300,"PeterIncome":200,"KenIncom":100,"freeCash":50},{"id":3295042,"tillPoint":"A","date":"22/01/2019","AnnaIncome":120,"PeterIncome":120,"KenIncom":30,"freeCash":50},{"id":3295042,"tillPoint":"B","date":"22/01/2019","AnnaIncome":100,"PeterIncome":150,"KenIncom":50,"freeCash":60},]
    
    const op = itemList.reduce((output,current)=>{
      let {id,tillPoint,date,freeCash,...rest} = current
     
      if(output[date]){
        output[date] = {
          ...output[date],
          ...rest,
          date,
          freeCash: output[date].freeCash +freeCash
        }
      } else {
        output[date] ={
          ...rest,
          date,
          freeCash
        }
      }
      return output
    },{})
    
    console.log(Object.values(op))
        3
  •  1
  •   mscdeveloper    7 年前

    const itemList = [
        { "id": 3295042, "tillPoint": "A", "date": "23/01/2019", "AnnaIncome": 100, "PeterIncome": 50,  "KenIncome": 100, "freeCash": 30 },
        { "id": 3295042, "tillPoint": "B", "date": "23/01/2019", "AnnaIncome": 300, "PeterIncome": 200, "KenIncome": 100, "freeCash": 50 },
        { "id": 3295042, "tillPoint": "A", "date": "22/01/2019", "AnnaIncome": 120, "PeterIncome": 120, "KenIncome": 30,  "freeCash": 50 },
        { "id": 3295042, "tillPoint": "B", "date": "22/01/2019", "AnnaIncome": 100, "PeterIncome": 150, "KenIncome": 50,  "freeCash": 60 },
    ];
    
    
    var new_itemList=[];
    
    for(var key in itemList){
    	var new_key = -1;
    	for(var keyn in new_itemList){
    	   if(new_itemList[keyn].date == itemList[key].date){
    	   	  new_key = parseInt(keyn, 10);
    	   }
    	}
    	if(new_key == -1){
    		new_itemList.push({'date':itemList[key].date, 'AnnaIncome': itemList[key].AnnaIncome, 'PeterIncome': itemList[key].PeterIncome, 'KenIncome': itemList[key].KenIncome, 'freeCash': itemList[key].freeCash});
    	}else{
           new_itemList[new_key].AnnaIncome +=  itemList[key].AnnaIncome;
           new_itemList[new_key].PeterIncome +=  itemList[key].PeterIncome;
           new_itemList[new_key].KenIncome +=  itemList[key].KenIncome;
           new_itemList[new_key].freeCash +=  itemList[key].freeCash;
    	}
    }
    console.log(new_itemList);