Heim  >  Fragen und Antworten  >  Hauptteil

Beste Möglichkeit, ein Array von Objekten zu gruppieren

Was ist der effizienteste Weg, Objekte in einem Array zu gruppieren?

Zum Beispiel dieses Array von Objekten:

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

Ich zeige diese Informationen in einer Tabelle an. Ich möchte nach verschiedenen Methoden gruppieren, aber die Werte summieren.

Ich verwende Underscore.js wegen seiner Groupby-Funktionalität, was sehr hilft, aber nicht das ganze Problem löst, weil ich nicht möchte, dass sie sich „aufteilen“, sondern „zusammenführen“, eher wie der SQL-Ansatz group by.

Ich möchte bei Bedarf die Summe bestimmter Werte berechnen können.

Wenn ich also Groupby mache Phase, erwarte ich Folgendes:

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

Wenn ich Groupy Phase / Step / Step ausführe, erhalte ich:

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

Gibt es ein nützliches Skript oder sollte ich bei Underscore.js bleiben und die Ergebnisobjekte durchlaufen, um die Gesamtsumme selbst zu berechnen?

P粉348915572P粉348915572375 Tage vor556

Antworte allen(2)Ich werde antworten

  • P粉933003350

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

    使用 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

    Antwort
    0
  • P粉681400307

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

    如果您想避免使用外部库,您可以简洁地实现 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"]}

    Antwort
    0
  • StornierenAntwort