搜索

首页  >  问答  >  正文

对对象数组进行分组的最佳方法

对数组中的对象进行分组的最有效方法是什么?

例如,给定这个对象数组:

1

2

3

4

5

6

7

8

9

10

[

    { 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,我希望收到:

1

2

3

4

[

    { Phase: "Phase 1", Value: 50 },

    { Phase: "Phase 2", Value: 130 }

]

如果我执行 groupy Phase / Step,我会收到:

1

2

3

4

5

6

[

    { 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粉348915572P粉348915572536 天前693

全部回复(2)我来回复

  • P粉933003350

    P粉9330033502023-10-10 22:01:48

    使用 ES6 Map 对象:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    39

    40

    41

    42

    43

    44

    45

    46

    47

    48

    49

    50

    /**

     * @description

     * Takes an Array<v>, 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<k, v="">(list: Array<v>, keyGetter: (input: V) => K): Map<k, array<v="">> {

    //    const map = new Map<k, array<v="">>();

    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]</k,></k,></v></k,></v>

    关于地图: https://developer.mozilla.org/en-US /docs/Web/JavaScript/Reference/Global_Objects/Map

    回复
    0
  • P粉681400307

    P粉6814003072023-10-10 09:27:55

    如果您想避免使用外部库,您可以简洁地实现 groupBy() 的普通版本,如下所示:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

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

    回复
    0
  • 取消回复