【问题标题】:Iterate over multi-dimensional array and return aggregated sum based on first index迭代多维数组并根据第一个索引返回聚合总和
【发布时间】:2018-05-08 18:56:21
【问题描述】:

我真的一直在为这个问题绞尽脑汁,因此非常感谢任何帮助。我目前有一个对象数组,每个对象都有两个属性,一个时间戳(自纪元以来的毫秒数)和该时间戳的任意属性。像这样:

[
    [1518739200000, 1], 
    [1518739200000, 1],
    [1518739200000, 12],
    [1518739200000, 16],
    [1518739200000, 16],
    [1518825600000, 16],
    [1518825600000, 20],
    [1518825600000, 20],
    [1518825600000, 8],
]

我要做的是将多维数组压缩成另一个多维数组,该数组只有第一个索引的唯一值、时间戳和作为第二个值的聚合计数。例如,我正在从上面包含的给定数据集中寻找它。

[
    [1518739200000, 46],
    [1518825600000, 64],
]

我已尝试以几种方式使用 .reduce,但对于这种特殊类型的操作尚未取得任何成功。

【问题讨论】:

标签: javascript arrays


【解决方案1】:

使用函数reduce的替代方法

let array = [[1518739200000, 1], [1518739200000, 1],[1518739200000, 12],[1518739200000, 16],[1518739200000, 16],[1518825600000, 16],[1518825600000, 20],[1518825600000, 20],[1518825600000, 8]];
let result = Object.values(array.reduce((a, [key, value]) => {
  (a[key] || (a[key] = [key, 0]))[1] += value;
  return a;
}, {}));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

  • 非常酷的东西,我很想把js写得这么简洁。你介意解释一下(x = [1,2])[1] += 1 是如何工作的,但(x = 1) += 1 没有。谢谢! +1
  • 有趣,你能解释一下为什么你使用 Object.values 和最后的空对象吗?我假设那是初始值,尽管我看到我们返回了一个多维数组(按要求),那么那里的空对象是什么?谢谢!
  • 思路是生成一个对象,键为常用次数,值为累计。在每次迭代中,如果该数字已经存在,则将该数字添加到该密钥的总数中,或者它为该时间创建一个新的密钥,其运行总数为0,然后立即添加当前数字。整个 reduce 调用将返回一个以 2d 数组作为值的对象,但如果传入Object.values,您只会得到一个值数组。
【解决方案2】:

您可以将 reduce 数组转换为 Map 并使用 Map 使用 Array.from 创建数组数组。

var data = [
  [1518739200000, 1], 
  [1518739200000, 1],
  [1518739200000, 12],
  [1518739200000, 16],
  [1518739200000, 16],
  [1518825600000, 16],
  [1518825600000, 20],
  [1518825600000, 20],
  [1518825600000, 8],
];

console.log(
  Array.from(
    data.reduce(
      (result,[current,num])=>
        result.set(
          current,
          (result.get(current)||0)+num
        ),
      new Map()
    )
  )
)

【讨论】:

    【解决方案3】:

    使用减少

    var x = [
            [1518739200000, 1], 
            [1518739200000, 1],
            [1518739200000, 12],
            [1518739200000, 16],
            [1518739200000, 16],
            [1518825600000, 16],
            [1518825600000, 20],
            [1518825600000, 20],
            [1518825600000, 8],
        ]
    
    x.reduce(function(ac,d,i,a){if(!ac.some(function(dd,ii){return dd[0] === d[0] && dd[1] === d[1]})){ac.push(d)
    }return ac},[]);
    

    上面得到了两个索引的唯一值,仅用于第一个:

    x.reduce(function(ac,d,i,a){if(!ac.some(function(dd,ii){return dd[0] === d[0]})){ac.push(d)}return ac},[])
    

    但是,问题是,这是第一个遇到的条目,你对第二个有什么偏好吗?

    更新:哇,我没有看到聚合,这是给它的:

    x.reduce(function(ac,d,i,a){
        var index;
        if(
            !ac.some(function(dd,ii){
                return dd[0] === d[0] ? (index=ii,true) : false
            })
        ){
            ac.push(d.slice())
        } else {
            ac[index][1] += d[1];
        }
        return ac
    },[])
    

    【讨论】:

      猜你喜欢
      • 2012-02-11
      • 1970-01-01
      • 1970-01-01
      • 2015-11-11
      • 1970-01-01
      • 1970-01-01
      • 2020-02-08
      • 2023-01-17
      • 1970-01-01
      相关资源
      最近更新 更多