2
votes

Un moyen simple de transformer un tableau d'objets en objet avec des clés groupées sous forme de tableaux

Je recherche un moyen simple de faire ce qui suit. J'ai essayé de le faire avec lodash.reduce et c'est maladroit, y a-t-il un moyen plus simple.

{a: ['meow', 'woof']}


1 commentaires

Envie de partager l'effort? Un utilisateur avec votre représentant doit en connaître l'importance


6 Réponses :


0
votes

J'ai eu quelques problèmes avec dactylographié et lodash.reduce, cela a fonctionné.

export function getFuncsObject(funcs): Record<Funcs, Case[]> {
  let f = { ...funcs };
  f = lodash.mapValues(f, () => []);
  return f;
}

export function mockMerge(funcs, mocks: Record<Funcs, Case | null>[]): Record<Funcs, Case[]> {
  const f = getFuncsObject(funcs);
  lodash.each(mocks, (v, k) => {
    f[k].push(v);
  });
  return f;
}


0 commentaires

2
votes

Vous pouvez le faire avec du JS pur, sans avoir besoin de loadash.

Appelez la méthode reduction des tableaux sur votre tableau d'entrée, et réduisez le tableau en objet, en boucle sur les clés de vos objets intérieurs:

const input = [{a: 'meow'}, {a: 'woof'}, {b: 'hi'}, {a: 'dog', c: 'bye'}, {}];

console.log(input.reduce((acc, val) => {
  Object.keys(val).forEach(key => {
    if(!acc[key]) {
      acc[key] = [];
    }
    acc[key].push(val[key]);
  });
  return acc;
}, {}));


1 commentaires

J'ai ajouté plus d'objets à l'ensemble d'entrée, juste pour montrer que cela fonctionne sur un ensemble généralisé. +1. Vous pouvez revenir en arrière si vous n'aimez pas cette modification. Je m'excuse dans ce cas



0
votes

Une option serait d'utiliser deux réductions comme suit:

const input = [{
  a: 'meow'
}, {
  a: 'woof'
}, {
  b: 'moo'
}];

const result = input
.reduce((itemResult, item) => Object.keys(item)
.reduce((keyResult, key) => ({
  ...keyResult,
  [key]: (keyResult[key] || []).concat(item[key])
}), itemResult), {});

console.log(result)

Je ne sais pas si c'est maladroit par rapport à votre solution actuelle, mais c'est assez concis et ne nécessite pas de bibliothèque externe.


0 commentaires

-1
votes
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

5 commentaires

Pouvez-vous partager une explication de votre solution? Cela ressemble à du code vraiment moche, et non à une "manière simple"


@NicoHaase, il itérera tout l'élément du tableau et pour chaque élément il vérifiera si la clé de cet élément existait dans l'objet o , si cela n'existe pas alors il initialisera sa valeur à value de cet élément sinon si la clé existe, il ajoutera la valeur de cet élément à l'objet avec la clé


Veuillez ajouter toutes les explications à votre question en la modifiant


@NicoHaase bien sûr, j'ai mis à jour ma réponse!


@NicoHaase Vous pouvez le vérifier à nouveau si vous avez besoin



2
votes

Vous pouvez utiliser lodash # assignWith pour attribuer toutes les propriétés leurs valeurs respectives en un seul objet, ainsi qu'une fonction de personnalisation pour déterminer comment vous souhaitez structurer l'objet.

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

Remarque: pour vous assurer que nous ne mutons aucun des objets dans le tableau data , j'ai passé un objet vide comme premier paramètre à agir comme objet de destination.

const data = [
  { a: 'meow' },
  { a: 'woof', k: 'hey' },
  { k: 'yo', d: 'hehe' },
  { d: 'wazup', q: 'ohoho' }
];

const result = _.assignWith({}, ...data, (v = [], s) => v.concat(s));

console.log(result);
const result = _.assignWith({}, ...data, (v = [], s) => v.concat(s));


2 commentaires

aussi, _.mergeWith peut être utilisé pour le même


Étant donné que la situation de l'OP ne traite pas de l'attribution récursive de valeurs, j'ai simplement choisi d'utiliser lodash # assignWith



0
votes

Sans utiliser de bibliothèques externes ni réduire.

const input = [ {a: 'meow'}, {a: 'woof'}, {b: 'hi'}, {a: 'dog', c: 'bye'}, {} ];
let output = {};

input.forEach((inputObj) => {
  for(let key in inputObj){
    if(!output[ key ]){
      output[ key ] = [];
    }
    output[ key ].push(inputObj[key])
  }
});


console.log(output);


0 commentaires