0

我最近发布了这个关于使用 d3.nest() 在 JavaScript 中对数组求和的问题

我得到了一个很好的解决方案(实际上是两个),但事实证明,当适应附加附加信息时,两者都有问题:

data = [
  {
    continent: 'africa',
    country: 'gabon',
    values: [1, 2]
  }, {
    continent: 'africa',
    country: 'chad',
    values: [3, 4]
  }, {
    continent: 'asia',
    country: 'china',
    values: [1, 2]
  }
];

sum_by = 'continent';

rollupAgg = function(data, sum_by) {
  return d3.nest().key(function(d) {
    return d[sum_by];
  }).rollup(function(group) {
    return group.reduce(function(prev, cur, index, arr) {
      return {
        values: prev.values.map(function(d, i) {
          return d + cur.values[i];
        }),
        sum_by: sum_by       // additional information
      };
    });
  }).entries(data);
};

如果该组中只有一行,reduce() 不会运行,因此返回以下内容:

[
  {
    "key": "africa",
    "values": {
      "values": [4, 6],
      "sum_by": "continent"
    }
  }, {
    "key": "asia",
    "values": {
      "continent": "asia",
      "country": "china",   // country information shouldn't have been retained
      "values": [1, 2]
    }                       // sum_by information should have been added
  }
];

您能找到一种修改此函数以使其返回所需结果的方法吗?

4

1 回答 1

1

到目前为止,我还没有想到单个元素数组不会执行该函数;但这是有道理的,因为您使用的是单个参数:

[].reduce(function(prev, curr, i, arr) {});// <-- function is the only param

当与单个参数一起使用时,行为是函数第一次执行时,i等于 1(不是 0),并且prevcurr数组的第一个和第二个元素。由于您只有一个元素,因此无法以这种形式调用它。

如果您将 reduce 与第二个参数一起使用:

[].reduce(function(prev, curr, i, arr) {}, { foo:'bar' });// <-- 2nd param {foo:bar}

它确实调用了该函数,第一个调用传递i等于 0 和prevequaling { foo:'bar' }

所以我猜你有两个选择:

  1. 要么修改它以传递第二个参数,在你的情况下需要它{ values:[0,0] }(并且硬编码始终是 2 个元素的事实,values如果它更长会导致问题)。

  2. 检查是否group.length == 1和如果是return group,而不是调用reduce。

于 2012-12-05T00:15:11.703 回答