是否可以使用 underscore.js 对 JSON 数据进行分组?

Is it possible to group this JSON data using underscore.js?

假设我有这个数据,它是查询的结果。

[
    [
        {
            "brgy_locat": "Kauswagan",
            "countlow": 8
        },
        {
            "brgy_locat": "Katugasan",
            "countlow": 24
        },
        {
            "brgy_locat": "Comagascas",
            "countlow": 3
        },
        {
            "counthigh": 7,
            "brgy_locat": "Barangay 9"
        },
        [
            {
                "brgy_locat": "Barangay 11",
                "countmedium": 1
            }
        ],
        [],
        [],
        [],
        [
            {
                "brgy_locat": "Mabini",
                "countmedium": 1
            }
        ],
        [
            {
                "counthigh": 27,
                "brgy_locat": "Barangay 6"
            },
            {
                "counthigh": 3,
                "brgy_locat": "Mabini"
            },
            {
                "counthigh": 2,
                "brgy_locat": "Barangay 2"
            },
            {
                "counthigh": 7,
                "brgy_locat": "Barangay 9"
            },
            {
                "counthigh": 17,
                "brgy_locat": "Comagascas"
            },
            {
                "counthigh": 1,
                "brgy_locat": "Tolosa"
            },
            {
                "counthigh": 33,
                "brgy_locat": "Barangay 7"
            }
        ]
    ]
]

我希望它按 brgy_locat 分组,如果 brgy_locat 相同,则对 countlowcountmediumcounthigh 的所有值求和。 有点像这样:

[
    {
        "brgy_locat": "Kauswagan",
        "countlow": 8,
        "countmedium": 1,
        "counthigh": 5
    }
]

上面的值只是示例。看看我做的这个JSFiddle

我第一次误解了这个问题。你还想压平,你还是可以用groupby。我发现使用 _.each 和索引参数在这方面非常有用。这应该为您完成:

var temp = _.chain(data)
    .flatten()
    .groupBy('brgy_locat')
    .each(function(eachObj,index) { 
        if (!result.findWhere({ 'brgy_locat': index })) {
            var newObj = {
                'brgy_locat': index,
                countlow: _.reduce(eachObj, function(memo, obj) {
                    if (!obj.countlow) return memo;
                    return memo + obj.countlow;
                },0),
                countmedium: _.reduce(eachObj, function(memo, obj) {
                    if (!obj.countmedium) return memo;
                    return memo + obj.countmedium;
                },0),
                counthigh: _.reduce(eachObj, function(memo, obj) {
                    if (!obj.counthigh) return memo;
                    return memo + obj.counthigh;
                },0)
            };
            result.push(newObj);
        }
    });

我看到你的fiddle,你应该添加一个flatten函数,让你的sum函数在undefined时将current转换为0 =]

你可以做这样的功能:

function sum(numbers) {
    return _.reduce(numbers, function (result, current) {
        return result + parseFloat(current || 0);
    }, 0);
}


function summarize(data) {
    var summary = _(data).chain()
    .flatten() 
    .groupBy("brgy_locat")
    .map(function (value, key) {
        return {
            brgy: key,
            low: sum(_(value).chain().pluck("countlow").value()),
            medium: sum(_(value).chain().pluck("countmedium").value()),
            high: sum(_(value).chain().pluck("counthigh").value())
        }
    })
    .value();

    return summary;
}

当您调用它传递您作为示例提供的数据时,结果将是您要求的...