0
votes

Créer un objet basé sur les clés d'un tableau d'objets

J'ai un tableau d'objets et je souhaite créer un autre objet en fonction de leurs clés. Par exemple, j'ai un tableau comme

var i = 1, new_arr = {};
_.reduce(arr, function(key, val){
     new_arr[i++] = temp1.key 
return new_arr;
},{})

et je veux mon tableau de résultats comme

var result = {1:[36011,19754,15711], 2:[18320,6722,10039],..}

On m'a suggéré d'utiliser lodash, je suis nouveau à ceci donc j'ai essayé d'utiliser la réduction

var arr = [{1: 36011, 2: 18320, 3: 36011, 4: 10570},
            {1: 19754, 2: 6722, 3: 19754, 4: 6699},
            {1: 15711, 2: 10039, 3: 15711, 4: 4172}]

J'obtiens les valeurs comme indéfinies . Quelle est l'erreur, quelqu'un peut-il m'aider?

image


2 commentaires

Il n'y a pas besoin de lodash, réduire est largement pris en charge. Nous sommes presque 2020! Le i dans votre code est global, donc il comptera toutes les valeurs. La réduction de votre code ne peut pas avoir de paire clé / valeur puisque vous l'appliquez à un tableau.


Aucune des questions indiquées dans "fermer comme double" ne contenait de réponse à cette question. Les deux concernaient le regroupement sur une seule propriété spécifique, alors qu'il s'agissait de fusionner plusieurs objets sur des propriétés arbitraires.


4 Réponses :


2
votes

Cela peut sembler intimidant au premier abord. Commencez à réduire l'ensemble de données à partir d'un objet vide. Ensuite, réduisez chaque ligne en commençant par le résultat de la réduction externe et tirez parti du résultat jusqu'à présent.

const addToBucket = (bucket = {}, k, v, prev = bucket[k] || []) => ({
  ...bucket,
  [k]: [...prev, v],
})

const toBucket = list =>
  list.reduce(
    (bucket, row) =>
      Object.entries(row).reduce((b, [k, v]) => addToBucket(b, k, v), bucket),
    {},
  )

const data = [
  { 1: 36011, 2: 18320, 3: 36011, 4: 10570 },
  { 1: 19754, 2: 6722, 3: 19754, 4: 6699 },
  { 1: 15711, 2: 10039, 3: 15711, 4: 4172 },
]

console.log(toBucket(data))

// Nested list, as requested
console.log(Object.entries(toBucket(data)).map(([_, v]) => v))


5 commentaires

Merci! Cela a été vraiment utile et j'ai appris un nouveau morceau de code aujourd'hui! @kornieff


Heureux d'avoir pu aider. Si mon code fait toujours peur, lisez simplement les fonctionnalités de déconstruction et de diffusion d'ES6. Bienvenue en 2020 🥳!


Si je veux créer le tout dans un tableau, pas un objet, comment dois-je le changer? @kornieff


Pouvez-vous me donner un exemple de ce à quoi vous voulez que cela ressemble?


J'ai ajouté une image à ma question. vérifiez-le @kornieff



0
votes

Vous pouvez essayer comme ça de la manière la plus simple.

Ceci est également disponible en ligne à l'adresse https://rextester.com/IPI35964 pour essayer de voir la sortie.

{ '1': [ 36011, 19754, 15711 ],
  '2': [ 18320, 6722, 10039 ],
  '3': [ 36011, 19754, 15711 ],
  '4': [ 10570, 6699, 4172 ] }

Sortie

var arr = [{1: 36011, 2: 18320, 3: 36011, 4: 10570},
        {1: 19754, 2: 6722, 3: 19754, 4: 6699},
        {1: 15711, 2: 10039, 3: 15711, 4: 4172}]

var output = {}
for(var obj of arr){
    for(var key in obj){
        if(key in output){
            output[key].push(obj[key])
        } else {
            output [key] = [obj[key]]
        }
    }
}
console.log(output)


0 commentaires

0
votes

Une façon assez simple de faire cela:

  • Créez un grand tableau de paires clé-valeur
  • Regroupez ces paires valeur / clé en fonction de leurs clés
  • Extraire les valeurs des paires clé-valeur groupées

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>
var arr = [
  { 1: 36011, 2: 18320, 3: 36011, 4: 10570 },
  { 1: 19754, 2: 6722, 3: 19754, 4: 6699 },
  { 1: 15711, 2: 10039, 3: 15711, 4: 4172 }
];

// Get one big array of all key-value pairs
var pairs = _.flatMap(arr, _.entries);

// Group by the keys (index 0 of the pairs)
var groups = _.groupBy(pairs, 0);

// Extract the values
var final = _.mapValues(groups, _.partial(_.map, _, 1));

//console.log(pairs);
console.log(final);


// Using chaining:
var final2 = _.chain(arr)
  .flatMap(_.entries)
  .groupBy(0)
  .mapValues(_.partial(_.map, _, 1));

console.log(final2);


0 commentaires

2
votes

avec lodash, vous pouvez utiliser _.mergeWith () et concater les valeurs dans la fonction de personnalisation:

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>
const arr = [{"1":36011,"2":18320,"3":36011,"4":10570},{"1":19754,"2":6722,"3":19754,"4":6699},{"1":15711,"2":10039,"3":15711,"4":4172}]
            
const result = _.mergeWith({}, ...arr, (ov = [], sv) => ov.concat(sv))

console.log(result)


0 commentaires