【问题标题】:How to create a distinct list from array and sum numeric values如何从数组和总和数值创建一个不同的列表
【发布时间】:2019-08-30 07:34:47
【问题描述】:

我有以下数组:

var array = []
array.push({payslipId: 1759});
array.push({payDate: "2019-04-19T00:00:00+00:00"});
array.push({periodsPerYear: 52});
array.push({taxPeriod: 2});
array.push({payslipId: 1760});
array.push({payDate: "2019-04-19T00:00:00+00:00"});
array.push({periodsPerYear: 52});
array.push({taxPeriod: 2});

我希望能够做的是创建一个不同名称的数组,如果值是数字,则将显示上述数组中所有的总数。

我能想到的唯一方法是创建一个新数组,并将每个name 添加到其中,然后循环上述数组,并将value 添加到name,如果值是数字。

我对javascript不太熟悉,所以希望有一个更简洁的方法,有点像C#中的linq

期望的输出:

[{ payslipId: 3519 }, { periodsPerYear: 104} , { taxPeriod: 4}]

【问题讨论】:

  • 该数组有四个不同的键值对:payslipIdpayDate、'periodsPerYear` 和 taxPeriod。当你说你想把数值相加时,你是指除了payDate之外的所有字段吗?为什么要添加payslipIdperiod 相关字段?
  • 你能展示你想要的输出是什么样子的吗?国际海事组织你正在寻找Object
  • 将所需的输出添加到问题中。
  • @PM77-1 嗯,理想情况下,我不想告诉函数字段是什么,我想对它进行分组,因为数组可以不同,我想要一个通用函数。

标签: javascript arrays


【解决方案1】:

您可以采用 Map 并通过采用对象的唯一键/值对来减少数组。

function group(array) {
    return Array.from(
        array.reduce((m, o) => {
            var [k, v] = Object.entries(o)[0];
            return typeof v === 'number'
                ? m.set(k, (m.get(k) || 0) + v)
                : m;
        }, new Map),
        ([k, v]) => ({ [k]: v })
    );
}

var array = [{ payslipId: 1759 }, { payDate: "2019-04-19T00:00:00+00:00" }, { periodsPerYear: 52 }, { taxPeriod: 2 }, { payslipId: 1760 }, { payDate: "2019-04-19T00:00:00+00:00" }, { periodsPerYear: 52 }, { taxPeriod: 2 }],
    result = group(array);

console.log(result);

【讨论】:

    【解决方案2】:

    正如我在原始帖子的评论中提到的,您可以使用reduce() 函数进行聚合。您可以应用聚合所需的任何条件。正如你所提到的,我只考虑了number 字段。

    给你:

    var array = []
    array.push({ payslipId: 1759 });
    array.push({ payDate: "2019-04-19T00:00:00+00:00" });
    array.push({ periodsPerYear: 52 });
    array.push({ taxPeriod: 2 });
    array.push({ payslipId: 1760 });
    array.push({ payDate: "2019-04-19T00:00:00+00:00" });
    array.push({ periodsPerYear: 52 });
    array.push({ taxPeriod: 2 });
    
    //console.log(array);
    result = array.reduce((aggr, item) => {
        itemKey = Object.keys(item)[0];
        if (Number.isInteger(item[itemKey])) {
            if (!aggr[itemKey]) {
                aggr[itemKey] = 0;
            }
            aggr[itemKey] = parseInt(aggr[itemKey]) + parseInt(item[itemKey]);
        }
        return aggr;
    }, {});
    console.log(result);

    【讨论】:

      【解决方案3】:

      另一种选择可能是:

      let array2 = [array[0]];
      array.shift();
      
      array.forEach(obj => {
        if(typeof(obj[Object.keys(obj)[0]]) !== 'number')  return;
        //test if the object with the same property name already exists to array2 or not. If it doesn't exist, it will be added to array2. If it does only the value will be added to the existing element
        let test = array2.reduce((accum,obj2) => {
          return accum && (Object.keys(obj2)[0] !== Object.keys(obj)[0]);
        }, true);
        if(test)     array2.push(obj);
        else  array2.find(obj2 => obj2.hasOwnProperty(Object.keys(obj)[0]))[Object.keys(obj)[0]] += obj[Object.keys(obj)[0]];
      });
      
      console.log(array2);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-09-29
        • 2013-04-21
        • 1970-01-01
        • 1970-01-01
        • 2015-06-29
        • 2015-10-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多