【问题标题】:Sum of nested JSON array using D3 .rollup使用 D3 .rollup 嵌套 JSON 数组的总和
【发布时间】:2017-02-24 21:30:57
【问题描述】:

我正在尝试获取嵌套对象数组中每个键的总和和平均值,如下所示:

    var data = [
    {department:'Electro',quant:{M:30, T:20, W:51, R:22, F:35 }},
    {department:'Beauty'',quant:{M:50, T:32, W:75, R:61, F: 45}},
    {department:'Apparel'',quant:{M:62, T:42, W:135, R: 82, F:89}},
    {department:'Misc',quant:{M:89, T:54, W:103, T:94, F:90}}
];

所以我需要分别计算每个部门的总和。即 sum = { 'Elecro': 158, 'Beauty': 263}

我正在使用汇总方法,但 examples 不适用于嵌套数组。

var deptSum = d3.nest()
.key(function(d) { return d.dept; })
.rollup(function(v) { return {
    count: v.length,
    total: d3.sum(v, function(d) {return d.quant; }),
    avg: d3.mean(v, function(d) {return d.quant; })
}; })
.entries(data)

console.log(JSON.stringify(deptSum))

但是总和是 0。

【问题讨论】:

    标签: javascript json d3.js


    【解决方案1】:

    有一种 D3 方法可以在汇总中获取总和(以及平均值)。然而,问题在于d3.sumd3.mean 都需要一个数组,但quant 只是一个对象:

    quant: {M:30, T:20, W:51, R:22, F:35 };
    

    解决方案:使用 D3 方法获取属性值,称为d3.values。根据documentation,它:

    返回一个包含指定对象属性值的数组(关联数组)。

    因此,您的rollup 应该是:

    .rollup(function(v) {
        return {
            count: v.length,
            total: d3.sum(d3.values(v[0].quant)),
            avg: d3.mean(d3.values(v[0].quant))
        };
    })
    

    这是一个演示:

    var data = [
        {department:'Electro',quant:{M:30, T:20, W:51, R:22, F:35 }},
        {department:'Beauty',quant:{M:50, T:32, W:75, R:61, F: 45}},
        {department:'Apparel',quant:{M:62, T:42, W:135, R: 82, F:89}},
        {department:'Misc',quant:{M:89, T:54, W:103, T:94, F:90}}
    ];
    
    var deptSum = d3.nest()
    .key(function(d) { return d.department; })
    .rollup(function(v) { return {
        count: v.length,
        total: d3.sum(d3.values(v[0].quant)),
        avg: d3.mean(d3.values(v[0].quant))
    }; })
    .entries(data)
    
    console.log(deptSum)
    <script src="https://d3js.org/d3.v4.min.js"></script>

    【讨论】:

      【解决方案2】:

      你甚至不需要 d3,这是一个纯 js 解决方案:

      var sumData = data.map(function(d) {
         var sum = Object.values(d.quant).reduce((a, b) => a + b)
         return { department: d.department, sum: sum}
      }).reduce(function(result, item) {
        result[item.department] = item.sum;
        return result;
      }, {})
      

      会给你{"Electro":158,"Beauty":263,"Apparel":410,"Misc":376}

      https://jsfiddle.net/96msy7jd/1

      【讨论】:

      • 这也有效,但似乎 D3 方法可以用更少的代码生成它,以获取嵌套数组的其他统计信息,如均值、计数等。我可能错了。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-04-20
      • 1970-01-01
      • 1970-01-01
      • 2015-10-17
      • 2016-04-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多