對(duì)數(shù)組中的對(duì)象進(jìn)行分組的最有效方法是什么?
例如,給定這個(gè)對(duì)象數(shù)組:
[ { Phase: "Phase 1", Step: "Step 1", Task: "Task 1", Value: "5" }, { Phase: "Phase 1", Step: "Step 1", Task: "Task 2", Value: "10" }, { Phase: "Phase 1", Step: "Step 2", Task: "Task 1", Value: "15" }, { Phase: "Phase 1", Step: "Step 2", Task: "Task 2", Value: "20" }, { Phase: "Phase 2", Step: "Step 1", Task: "Task 1", Value: "25" }, { Phase: "Phase 2", Step: "Step 1", Task: "Task 2", Value: "30" }, { Phase: "Phase 2", Step: "Step 2", Task: "Task 1", Value: "35" }, { Phase: "Phase 2", Step: "Step 2", Task: "Task 2", Value: "40" } ]
我正在表格中顯示此信息。我想按不同的方法進(jìn)行分組,但我想對(duì)值進(jìn)行求和。
我使用 Underscore.js 來實(shí)現(xiàn)其 groupby 功能,這很有幫助,但并不能解決全部問題,因?yàn)槲也幌M鼈儭安鸱帧倍恰昂喜ⅰ?,更像?SQL group by
方法。
我正在尋找能夠計(jì)算具體值的總和(如果需要的話)。
因此,如果我執(zhí)行 groupby Phase
,我希望收到:
[ { Phase: "Phase 1", Value: 50 }, { Phase: "Phase 2", Value: 130 } ]
如果我執(zhí)行 groupy Phase
/ Step
,我會(huì)收到:
[ { Phase: "Phase 1", Step: "Step 1", Value: 15 }, { Phase: "Phase 1", Step: "Step 2", Value: 35 }, { Phase: "Phase 2", Step: "Step 1", Value: 55 }, { Phase: "Phase 2", Step: "Step 2", Value: 75 } ]
是否有一個(gè)有用的腳本,或者我應(yīng)該堅(jiān)持使用 Underscore.js,然后循環(huán)遍歷結(jié)果對(duì)象來自己計(jì)算總計(jì)?
使用 ES6 Map 對(duì)象:
/** * @description * Takes an Array, and a grouping function, * and returns a Map of the array grouped by the grouping function. * * @param list An array of type V. * @param keyGetter A Function that takes the the Array type V as an input, and returns a value of type K. * K is generally intended to be a property key of V. * * @returns Map of the array grouped by the grouping function. */ //export function groupBy (list: Array , keyGetter: (input: V) => K): Map > { // const map = new Map >(); function groupBy(list, keyGetter) { const map = new Map(); list.forEach((item) => { const key = keyGetter(item); const collection = map.get(key); if (!collection) { map.set(key, [item]); } else { collection.push(item); } }); return map; } // example usage const pets = [ {type:"Dog", name:"Spot"}, {type:"Cat", name:"Tiger"}, {type:"Dog", name:"Rover"}, {type:"Cat", name:"Leo"} ]; const grouped = groupBy(pets, pet => pet.type); console.log(grouped.get("Dog")); // -> [{type:"Dog", name:"Spot"}, {type:"Dog", name:"Rover"}] console.log(grouped.get("Cat")); // -> [{type:"Cat", name:"Tiger"}, {type:"Cat", name:"Leo"}] const odd = Symbol(); const even = Symbol(); const numbers = [1,2,3,4,5,6,7]; const oddEven = groupBy(numbers, x => (x % 2 === 1 ? odd : even)); console.log(oddEven.get(odd)); // -> [1,3,5,7] console.log(oddEven.get(even)); // -> [2,4,6]
關(guān)于地圖: https://developer.mozilla.org/en-US /docs/Web/JavaScript/Reference/Global_Objects/Map
如果您想避免使用外部庫,您可以簡(jiǎn)潔地實(shí)現(xiàn) groupBy()
的普通版本,如下所示:
var groupBy = function(xs, key) { return xs.reduce(function(rv, x) { (rv[x[key]] = rv[x[key]] || []).push(x); return rv; }, {}); }; console.log(groupBy(['one', 'two', 'three'], 'length')); // => {"3": ["one", "two"], "5": ["three"]}