2 votes

Javascript : comparez les propriétés des éléments d'un tableau, et si elles sont identiques, combinez-les.

J'ai affaire à un tableau d'objets. Chaque objet a deux propriétés, size et count.

var drives = [
{size:"900GB", count:3},
{size:"900GB", count:100},
{size:"1200GB", count:5},
{size:"900GB", count:1}
]

Je n'aime pas que la même taille apparaisse plusieurs fois, et je voudrais consolider toutes les tailles répétées en un seul index de tableau.

D'abord, j'ai le tableau trié par taille. Ensuite, j'ai essayé de faire un for-loop pour gérer les répétitions.

drives.sort(function(obj1, obj2) {
var First = parseInt(obj1.size)
var Second = parseInt(obj2.size)
// Ascending: first size less than the previous
return First - Second;
})

for(var i = 0; i < drives.length-1; i++)
 {

    if(drives[i].size == drives[i+1].size)
     {
        drives[i+1].count+=drives[i].count; 
        //add the count of the first index to the second index's count
        drives.splice(i, 1); 
        //delete the first index
     }
 }          

https://jsbin.com/zayofiqoke/edit?js,console

Le for-loop ne semble pas itérer correctement. Elle ne combine que deux index. Comment puis-je obtenir ce que je cherche ? Merci !

0voto

Nina Scholz Points 17120

Vous pourriez filtrer le tableau et mettre à jour les éléments de même taille avec une fermeture sur une table de hachage.

var drives = [{ size: "900GB", count: 3 }, { size: "900GB", count: 100 }, { size: "1200GB", count: 5 }, { size: "900GB", count: 1 }];

drives = drives.filter(function (hash) {
    return function (a) {
        if (!hash[a.size]) {
            hash[a.size] = a;
            return true;
        }
        hash[a.size].count += a.count;
    };
}(Object.create(null)));

console.log(drives);

0voto

Patrick Barr Points 998

Ce n'est probablement pas la meilleure mise en œuvre, mais vous pouvez toujours conserver une liste temporaire d'éléments et la parcourir par itération :

var tmp = {};
var out = [];
for(var i = 0; i < drives.length; i++) {
    if(!tmp[JSON.stringify(drives[i])]) {
        out.push(drives[i]);
        tmp[JSON.stringify(drives[i])] = true;
    }
}

Tout ce que je fais, c'est itérer dans le tableau, je convertis l'objet en JSON et je l'utilise comme clé dans un objet, donc s'il y a des objets identiques, ils seront, je l'espère, pris en compte parce qu'ils existent dans l'objet temporaire (la recherche continue à ~O(1) stringify itère sur les clés dans une boucle).

Si la clé n'a pas été définie, poussez l'objet vers un nouveau tableau et continuez jusqu'à la fin de votre tableau original.

Ainsi, votre solution finale s'exécute en O(n) mais elle n'est pas très efficace en termes de mémoire.

0voto

gyre Points 11358

Edita: On pourrait éventuellement faire encore plus court en utilisant Array#filter . Crédit à Nina Scholz pour avoir posté la première réponse utilisant cette stratégie. J'utilise le deuxième argument de la méthode filter qui définit la fonction this donné au callback passé, afin d'utiliser le moins de lignes supplémentaires possible.

var drives = [
  {size:"900GB", count:3},
  {size:"900GB", count:100},
  {size:"1200GB", count:5},
  {size:"900GB", count:1}
]

var result = drives.filter(function (e) {
  if (e.size in this) this[e.size].count += e.count
  else return this[e.size] = e
}, {})

console.log(result)

Original : Une meilleure approche pourrait être d'utiliser Array#map y Array#reduce :

var drives = [
  {size:"900GB", count:3},
  {size:"900GB", count:100},
  {size:"1200GB", count:5},
  {size:"900GB", count:1}
]

var map = drives.reduce(function (map, e) {
  if (e.size in map) map[e.size].count += e.count
  else map[e.size] = e
  return map
}, {})

var result = Object.keys(map).map(function (k) {
  return this[k]
}, map)

console.log(result)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X