web-dev-qa-db-fra.com

JavaScript - Réduire le tableau d'objets par clé

Travailler avec un tableau d'objets comme:

const arr = [
  {name: "qewregf dqewafs", value: "qewregf dqewafs answer", count: 2},
  {name: "survey with select", value: "survey with select answer", count: 2},
  {name: "werasd", value: "Donald", count: 1},
  {name: "werasd", value: "Jim", count: 1}
];

J'essaie de réduire le tableau sur les valeurs correspondantes pour la clé name et d'obtenir une sortie souhaitée comme:

desiredOutput = [
  {name: "qewregf dqewafs", data: [{value: "qewregf dqewafs answer", count: 2}]},
  {name: "survey with select", data: [{value: "survey with select answer", count: 2}]},
  {name: "werasd", data: [{value: "Donald", count: 1}, {value: "Jim", count: 1}]}
]

Cette tentative réduit le tableau, mais je ne sais pas comment fusionner les valeurs imbriquées sans écraser.

const arr = [{"name":"qewregf dqewafs","value":"qewregf dqewafs answer","count":2},{"name":"survey with select","value":"survey with select answer","count":2},{"name":"werasd","value":"Donald","count":1},{"name":"werasd","value":"Jim","count":1}];

const result = arr.reduce((acc, d) => {
  const found = acc.find(a => a.name === d.name);
  const value = { name: d.name, val: d.value };
  if (found) {
    acc.Push(...value);
  }
  else {
    acc.Push({ name: d.name, data: [{ value: d.value }, { count: d.count }] });
  }
  return acc;
}, []);

console.log(result);

Qu'est-ce que je rate?

4
proph3t

Vos codes sont un peu proches de l'objectif, il suffit juste d'ajuster quelque chose.

Veuillez voir le commentaire dans la démo ci-dessous:

  1. Quand acc.find ne trouve rien, puis pousser un élément {name:d.name, data: [value]}

  2. s'il est trouvé, appuyez sur un {value: ...} dans la propriété data.

const arr = [
  {name: "qewregf dqewafs", value: "qewregf dqewafs answer", count: 2},
  {name: "survey with select", value: "survey with select answer", count: 2},
  {name: "werasd", value: "Donald", count: 1},
  {name: "werasd", value: "Jim", count: 1}
];

const result = arr.reduce((acc, d) => {
  const found = acc.find(a => a.name === d.name);
  //const value = { name: d.name, val: d.value };
  const value = { value: d.value, count: d.count }; // the element in data property
  if (!found) {
    //acc.Push(...value);
    acc.Push({name:d.name, data: [value]}) // not found, so need to add data property
  }
  else {
    //acc.Push({ name: d.name, data: [{ value: d.value }, { count: d.count }] });
    found.data.Push(value) // if found, that means data property exists, so just Push new element to found.data.
  }
  return acc;
}, []);

console.log(result)
7
Sphinx

Créez simplement une carte avec le nom comme clé et utilisez Object destructing Et Object.values() pour obtenir le résultat souhaité.

const arr = [
  {name: "qewregf dqewafs", value: "qewregf dqewafs answer", count: 2},
  {name: "survey with select", value: "survey with select answer", count: 2},
  {name: "werasd", value: "Donald", count: 1},
  {name: "werasd", value: "Jim", count: 1}
];

let result = Object.values(arr.reduce((a,{name, ...props})=>{
  if(!a[name])
     a[name]  = Object.assign({}, {name,data : [props]});
   else
    a[name].data.Push(props);
  return a;
},{}));

console.log(result);
0
amrender singh

Vous pouvez simplifier l'utilisation de l'objet trouvé en vérifiant s'il n'existe pas et en poussant un nouvel objet vers le jeu de résultats.

Poussez ensuite un objet avec value et count vers data.

const
    array = [{ name: "qewregf dqewafs", value: "qewregf dqewafs answer", count: 2 }, { name: "survey with select", value: "survey with select answer", count: 2 }, { name: "werasd", value: "Donald", count: 1 }, { name: "werasd", value: "Jim", count: 1 }],
    result = array.reduce((r, { name, value, count }) => {
        var temp = r.find(o => name === o.name);
        if (!temp) {
            r.Push(temp = { name, data: [] });
        }
        temp.data.Push({ value, count });
        return r;
    }, []);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
0
Nina Scholz

Vous devez faire quelque chose comme ceci:

const arr = [
  {name: "qewregf dqewafs", value: "qewregf dqewafs answer", count: 2},
  {name: "survey with select", value: "survey with select answer", count: 2},
  {name: "werasd", value: "Donald", count: 1},
  {name: "werasd", value: "Jim", count: 1}
];

const result = arr.reduce((acc, d) => {
  let idx = acc.findIndex(a => a.name === d.name);
  let val = { value: d.value, count: d.count };

  if (idx > -1) {
    acc[idx].data.Push(val);
  } else {
    acc.Push({ name: d.name, data: [val] });
  }

  return acc;
}, []);

console.log(result);

Vous devez d'abord trouver l'index, puis pousser vos données dans cette ligne. Vous ne faites que le trouver, mais poussez ensuite une nouvelle valeur dans le tableau.

0
WakeskaterX

Vous n'êtes pas loin. Ce serait une simple modification de deux lignes de votre code pour y parvenir:

const arr = [
  {name: "qewregf dqewafs", value: "qewregf dqewafs answer", count: 2},
  {name: "survey with select", value: "survey with select answer", count: 2},
  {name: "werasd", value: "Donald", count: 1},
  {name: "werasd", value: "Jim", count: 1}
];

const result = arr.reduce((acc, d) => {
  const found = acc.find(a => a.name === d.name);
  const value = { name: d.name, val: d.value };
  if (found) {
    found.data.Push(value);
  }
  else {
    acc.Push({ name: d.name, data: [{ value: d.value, count: d.count }] });
  }
  return acc;
}, []);

console.log(result)

Voici les différences:

-     acc.Push(...value);
+     found.data.Push(value);


-    acc.Push({ name: d.name, data: [{ value: d.value }, { count: d.count }] });
+    acc.Push({ name: d.name, data: [{ value: d.value, count: d.count }] });
0
Scott Sauyet