Heim  >  Fragen und Antworten  >  Hauptteil

Der effizienteste Weg, Objektarrays zu gruppieren

<p>Wie lassen sich Objekte in einem Array am effizientesten gruppieren? </p> <p>Zum Beispiel das folgende Array von Objekten: </p> <pre class="brush:php;toolbar:false;">[ { Phase: „Phase 1“, Schritt: „Schritt 1“, Aufgabe: „Aufgabe 1“, Wert: „5“ }, { Phase: „Phase 1“, Schritt: „Schritt 1“, Aufgabe: „Aufgabe 2“, Wert: „10“ }, { Phase: „Phase 1“, Schritt: „Schritt 2“, Aufgabe: „Aufgabe 1“, Wert: „15“ }, { Phase: „Phase 1“, Schritt: „Schritt 2“, Aufgabe: „Aufgabe 2“, Wert: „20“ }, { Phase: „Phase 2“, Schritt: „Schritt 1“, Aufgabe: „Aufgabe 1“, Wert: „25“ }, { Phase: „Phase 2“, Schritt: „Schritt 1“, Aufgabe: „Aufgabe 2“, Wert: „30“ }, { Phase: „Phase 2“, Schritt: „Schritt 2“, Aufgabe: „Aufgabe 1“, Wert: „35“ }, { Phase: „Phase 2“, Schritt: „Schritt 2“, Aufgabe: „Aufgabe 2“, Wert: „40“ } ]</pre> <p>Ich zeige diese Informationen in einer Tabelle an. Ich möchte nach verschiedenen Methoden gruppieren, aber die Werte summieren. </p> <p>Ich verwende die Groupby-Funktion von Underscore.js, die hilfreich ist, aber den Bedarf nicht ganz befriedigt, weil ich sie nicht „trennen“, sondern „zusammenführen“ möchte, eher wie die Gruppierung nach SQL Methode. </p> <p>Was ich möchte, ist, bei Bedarf bestimmte Werte summieren zu können. </p> <p>Wenn ich also nach <code>Phase</code> gruppiere, möchte ich Folgendes erhalten: </p> <pre class="brush:php;toolbar:false;">[ { Phase: „Phase 1“, Wert: 50 }, { Phase: „Phase 2“, Wert: 130 } ]</pre> <p>Wenn ich nach <code>Phase</code> / <code>Step</code> gruppiere, möchte ich Folgendes erhalten: </p> <pre class="brush:php;toolbar:false;">[ { Phase: „Phase 1“, Schritt: „Schritt 1“, Wert: 15 }, { Phase: „Phase 1“, Schritt: „Schritt 2“, Wert: 35 }, { Phase: „Phase 2“, Schritt: „Schritt 1“, Wert: 55 }, { Phase: „Phase 2“, Schritt: „Schritt 2“, Wert: 75 } ]</pre> <p>Gibt es ein nützliches Skript, um dies zu erreichen, oder sollte ich einfach weiterhin Underscore.js verwenden und die Summierung durch Durchlaufen der Ergebnisobjekte durchführen? </p>
P粉310754094P粉310754094426 Tage vor563

Antworte allen(2)Ich werde antworten

  • P粉029327711

    P粉0293277112023-08-22 12:54:13

    使用ES6的Map对象:

    /**
     * @description
     * 接受一个类型为V的数组和一个分组函数,返回按照分组函数分组的数组的Map。
     *
     * @param list 类型为V的数组。
     * @param keyGetter 一个函数,接受类型为V的数组作为输入,并返回类型为K的值。
     *                  K通常是V的属性键。
     *
     * @returns 按照分组函数分组的数组的Map。
     */
    //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;
    }
    
    
    // 使用示例
    
    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]

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

    Antwort
    0
  • P粉590428357

    P粉5904283572023-08-22 11:08:27

    如果您想避免使用外部库,可以简洁地实现一个原生版本的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