【问题标题】:Aggregate and transform array of objects聚合和转换对象数组
【发布时间】:2016-05-12 03:26:04
【问题描述】:

使用javascript函数式编程方法(如map/reduce),如何聚合/计算arr1status字段并将其转换为arr2中的键/值对象数组。

arr1 = [
  {'task':'do something 1', 'status':'done'} , 
  {'task':'do something 2', 'status':'done'} , 
  {'task':'do something 3', 'status':'pending'} , 
  {'task':'do something 4', 'status':'done'}
];

// Aggregate arr1 `status` field and transform to:

arr2 = [
  {key:'done', value: 3},
  {key:'pending', value: 1}
];

这是我的 WIP 部分解决方案,它处理聚合部分。我仍然需要转换部分。

var arr2 = arr1.map(function(item) {
    return item.status;
  }).reduce(function(acc,curr,idx){
    if(acc[curr] === undefined) acc[curr] = 1;
    else acc[curr] += 1;
    return acc;
  }, []); 

【问题讨论】:

  • 我只想做this,但不确定它是否足够“实用”。
  • 您的解决方案没有给出预期的答案。或者提供的答案不正确。
  • 我相信@Kiril 是对的,贴出的代码会产生[done: 3, pending: 1],或者换句话说,它将数组视为对象,并且不会返回预期的结果?
  • @adeneo,您的解决方案很棒。为什么不将其发布为答案?
  • @jboothe - 不太确定这是你想要的,但我会为后代发布

标签: javascript arrays dictionary functional-programming map-function


【解决方案1】:

这是我能想到的最实用的方法。这包括聚合和您想要的转换:

var arr2 = Object.keys(arr2 = arr1.map(function(item) {
    return item.status;
}).reduce(function(acc,curr){
    acc[curr] = acc[curr] + 1 || 1;
    return acc;
}, [])).map(function(item){
    return {key: item, value: arr2[item]}
});

【讨论】:

  • 亚历克斯,做得很好。我要做的唯一清理是对我自己的代码 - 将第 4 行和第 5 行合并为一个三元组 acc[curr] === undefined ? acc[curr] = 1 : acc[curr] + 1;
  • @jboothe 好点!我也在考虑三元,但想出了一个更紧凑的解决方案,你怎么看?
  • 漂亮。未定义 + 1 或 1。
【解决方案2】:

你可以试试Array.prototype.forEach()。此外,您可以使用 object 来代替使用数组。这将避免您循环查找特定状态的计数。

arr1 = [
  {'task':'do something 1', 'status':'done'} , 
  {'task':'do something 2', 'status':'done'} , 
  {'task':'do something 3', 'status':'pending'} , 
  {'task':'do something 4', 'status':'done'}
];

var result = {};
arr1.forEach(function(item){
  if(!result[item.status])
    result[item.status] = 0;
  
  result[item.status]++;
});
console.log(result);

【讨论】:

    【解决方案3】:

    由于您将输出值存储为数组,因此您应该检查天气键状态是否存在。如果存在,则增加其值。

    arr2 = [];
    arr1.forEach(function(item){
      var keyPresent = false;
      for(var i = 0, len = arr2.length; i < len; i++) {
          if( arr2[ i ].key === item.status ){
             keyPresent = true;
             arr2[ i ].value++
          }
      }
      if(!keyPresent){
        arr2.push({key: item.status , value : 1})
    }
    

    给出的输出
    arr2 = [
      {key:'done', value: 3},
      {key:'pending', value: 1}
    ];
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-21
      • 1970-01-01
      • 1970-01-01
      • 2022-01-21
      • 2019-06-10
      • 1970-01-01
      相关资源
      最近更新 更多