Summing arrays in JavaScript using d3.nest() Part II

一世执手 提交于 2020-01-06 07:24:37

问题


I recently posted this question about summing arrays in JavaScript using d3.nest()

I got a good solution (two in fact), but it turns out both have an issue when adapted to append additional information:

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() doesn't run if there is only one row in that group, so this returns the following:

[
  {
    "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
  }
];

Can you see a way to modify this function so that it returns the desired result?


回答1:


Hasn't occurred to me till now that a single element array will not execute the function; but it makes sense, because you're using with a single param:

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

When used with a single param, the behavior is that the first time the function is executed, i equals 1 (not 0), and prev and curr are the first and second elements of the array. Since you only have one element, there's no way to call it in this form.

If you use reduce with a 2nd param:

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

it does actually call the function, with the first call passing i equal to 0 and prev equaling { foo:'bar' }.

So I guess you have 2 options:

  1. Either modify it to pass a 2nd param, which in your case would need to be { values:[0,0] } (and that hardcodes the fact that values is always 2 elements, which will cause an issue if it's longer).

  2. Check if group.length == 1 and if so, return group, instead of calling reduce.



来源:https://stackoverflow.com/questions/13713784/summing-arrays-in-javascript-using-d3-nest-part-ii

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!