Meilleure façon de regrouper un tableau d'objets
P粉348915572
P粉348915572 2023-10-09 22:39:14
0
2
615

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粉348915572
P粉348915572

répondre à tous(2)
P粉933003350

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

P粉681400307

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"]}
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal