javascript - 如何聚合对象属性?

标签 javascript

如果我有这样(或类似)的对象:

sales = { 
    obs1:{
        Sales1:{
            Region:"North", Value: 200}, 
        Sales2:{
            Region:"South", Value:100}}, 
    obs2:{
        Sales1:{
            Region:"North", Value: 50}, 
        Sales2:{
            Region:"South", Value:20}
    }
}

如何按 Region 汇总属性 Value 的总和?答案可以是纯 JavaScript 或库。

最终结果应该是这样的:

totals = {North: 250, South:120}

最佳答案

正如其他人所指出的,没有内置的 JavaScript 函数可以执行此操作(有一些高阶函数,如 map,但不足以完成任务)。但是,一些库,例如 Underscore.js提供许多实用程序来简化此类任务。

var totals = _
    .chain(sales) // Wraps up the object in an "underscore object",
                  // so methods can be chained
    // First: "flatten" the sales
    .map(function(v) { 
        return _
            .chain(v)
            .map(function(v2) {
                return v2;
            })
            .value(); 
    })
    .flatten()
    // Second: group the sales by region
    .groupBy('Region')
    // Third: sum the groups and create the object with the totals
    .map(function(g, key) {
        return {
            type: key, 
            val: _(g).reduce(function(m, x) {
                return m + x.Value;
            }, 0)
        };
    })
    .value(); // Unwraps the "underscore object" back to a plain JS object

来源:this answer at SOpt

此答案假设您的数据的结构 已知 - 与其他答案相反,后者侧重于概括结构。虽然上面的代码可以通过删除硬编码的 RegionValue 并将嵌套级别更改为除两个以外的其他内容并将聚合函数更改为除 sum 之外的其他内容 -只要叶子包含您要分组的属性和您想要聚合的值。

function aggregate(object, toGroup, toAggregate, fn, val0) {
    function deepFlatten(x) {
        if ( x[toGroup] !== undefined ) // Leaf
            return x;
        return _.chain(x)
                .map(function(v) { return deepFlatten(v); })
                .flatten()
                .value();
    }

    return _.chain(deepFlatten(object))
            .groupBy(toGroup)
            .map(function(g, key) {
                return {
                    type: key,
                    val: _(g).reduce(function(m, x) {
                        return fn(m, x[toAggregate]);
                    }, val0 || 0)
                };
            })
            .value();
}

它的名字是这样的:

function add(a,b) { return a + b; }
var totals = aggregate(sales, "Region", "Value", add);

另一个例子(按地区求最小值):

function min(a,b) { return a < b ? a : b; }
var mins = aggregate(sales, "Region", "Value", min, 999999);

关于javascript - 如何聚合对象属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23521894/

相关文章:

javascript - 有两列的谷歌柱形图

javascript - 为什么 this.props.map 不是一个函数?

javascript从类名分配函数

javascript - Angular JS 中的 ngcontroller

javascript - 为 XHR 请求渲染 js.erb

javascript - 如何在 TypeScript 的 Vue Composition API 中响应式访问当前路由名称?

javascript - 从被点击的元素image src中放入image src并更新数据

javascript - JS 正则表达式匹配单词,包括空格包围的单词

javascript - 提交 redux-form 时如何引用 prop

javascript - 平滑滚动条不适用于主体元素