Maison  >  Questions et réponses  >  le corps du texte

Meilleure façon de regrouper un tableau d'objets

Quel est le moyen le plus efficace de regrouper des objets dans un tableau ?

Par exemple, étant donné ce tableau d'objets :

[ 
    { 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'affiche ces informations dans un tableau. Je veux regrouper par différentes méthodes mais je veux additionner les valeurs.

J'utilise Underscore.js pour sa fonctionnalité groupby, ce qui aide beaucoup, mais ne résout pas tout le problème car je ne veux pas qu'ils se "scindent" mais "fusionnent", plus comme l'approche SQL group by.

Je cherche à pouvoir calculer la somme de valeurs spécifiques si besoin.

Donc si je fais groupby Phase j'attends de recevoir :

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

Si j'exécute groupy Phase / Step / Step, je reçois :

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

Existe-t-il un script utile ou dois-je m'en tenir à Underscore.js et parcourir les objets de résultat pour calculer moi-même le total ?

P粉348915572P粉348915572376 Il y a quelques jours558

répondre à tous(2)je répondrai

  • P粉933003350

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

    Utilisez l'objet Carte ES6 :

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

    À propos de la carte : https://developer.mozilla.org/en-US /docs/Web/JavaScript/Reference/Global_Objects/Map

    répondre
    0
  • P粉681400307

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

    Si vous souhaitez éviter d'utiliser des bibliothèques externes, vous pouvez simplement implémenter la version simple de groupBy() comme ceci :

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

    répondre
    0
  • Annulerrépondre