對物件數組進行分組的最佳方法
P粉348915572
P粉348915572 2023-10-09 22:39:14
0
2
596

對數組中的物件進行分組的最有效方法是什麼?

例如,給定這個物件數組:

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

我正在表格中顯示此資訊。我想按不同的方法進行分組,但我想對值進行求和。

我使用Underscore.js 來實現其groupby 功能,這很有幫助,但並不能解決全部問題,因為我不希望它們“拆分”而是“合併”,更像是SQL group by 方法。

我正在尋找能夠計算具體值的總和(如果需要的話)。

因此,如果我執行 groupby Phase,我希望收到:

[
    { Phase: "Phase 1", Value: 50 },
    { Phase: "Phase 2", Value: 130 }
]

如果我執行 groupy Phase / Step,我會收到:

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

是否有一個有用的腳本,或者我應該堅持使用 Underscore.js,然後循環遍歷結果物件來自己計算總計?

P粉348915572
P粉348915572

全部回覆(2)
P粉933003350

使用 ES6 Map 物件:

/**
 * @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]

關於地圖: https://developer.mozilla.org/en-US /docs/Web/JavaScript/Reference/Global_Objects/Map

P粉681400307

如果您想避免使用外部函式庫,您可以簡潔地實作 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"]}
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板