J'ai un tableau d'objets comme celui-ci:
_.chain(channels)
.groupBy("type.name")
.map((item, i) => {
return {
chunks: item,
by: i
};
})
.value();
Ce que j'essaie de faire, c'est de regrouper ces objets par type key: value dans ce cas par nom: valeur , comme ceci:
const data = [
{
by: {
type: { name: "A" }
},
chunks: [
{ id: 1, type: { name: "A" }, condition: "new" },
{ id: 6, type: { name: "A" }, condition: "new" },
{ id: 7, type: { name: "A" }, condition: "new" }
]
},
{
by: {
type: { name: "C" }
},
chunks: [
{ id: 2, type: { name: "C" }, condition: "broken" },
{ id: 3, type: { name: "C" }, condition: "brand new" },
{ id: 5, type: { name: "C" }, condition: "brand new" },
{ id: 9, type: { name: "C" }, condition: "broken" }
]
},
{
by: {
type: { name: "B" }
},
chunks: [
{ id: 4, type: { name: "B" }, condition: "broken" },
{ id: 8, type: { name: "B" }, condition: "broken" }
]
},
];
J'ai essayé d'utiliser lodash et Array.prototype.reduce () code>, ma dernière tentative utilisait lodash, mais je ne peux pas obtenir le type en tant qu'objet.
const data = [
{ id: 1, type: { name: "A" }, condition: "new" },
{ id: 2, type: { name: "C" }, condition: "broken" },
{ id: 3, type: { name: "C" }, condition: "brand new" },
{ id: 4, type: { name: "B" }, condition: "broken" },
{ id: 5, type: { name: "C" }, condition: "brand new" },
{ id: 6, type: { name: "A" }, condition: "new" },
{ id: 7, type: { name: "A" }, condition: "new" },
{ id: 8, type: { name: "B" }, condition: "broken" },
{ id: 9, type: { name: "C" }, condition: "broken" }
];
8 Réponses :
Vous pouvez utiliser une Carte pour collecter les données par groupe, puis sa méthode values () itérera les données comme vous le souhaitez:
p >
const data = [{ id: 1, type: { name: "A" }, condition: "new" },{ id: 2, type: { name: "C" }, condition: "broken" },{ id: 3, type: { name: "C" }, condition: "brand new" },{ id: 4, type: { name: "B" }, condition: "broken" },{ id: 5, type: { name: "C" }, condition: "brand new" },{ id: 6, type: { name: "A" }, condition: "new" },{ id: 7, type: { name: "A" }, condition: "new" },{ id: 8, type: { name: "B" }, condition: "broken" },{ id: 9, type: { name: "C" }, condition: "broken" }];
const map = new Map(data.map(o => [o.type.name, { by: { type: o.type.name }, chunks: [] }]));
data.forEach(o => map.get(o.type.name).chunks.push(o));
const result = [...map.values()];
console.log(result);
Vous pouvez utiliser réduire
Voici l'idée
nom comme clé et vérifie si op a déjà cette clé particulière ou non. si la clé est déjà là, nous poussons la propriété inp vers chunks de op. sinon nous ajoutons une nouvelle clé avec by et morceaux avec des valeurs respectives.
const data = [{ id: 1, type: { name: "A" }, condition: "new" },{ id: 2, type: { name: "C" }, condition: "broken" },{ id: 3, type: { name: "C" }, condition: "brand new" },{ id: 4, type: { name: "B" }, condition: "broken" },{ id: 5, type: { name: "C" }, condition: "brand new" },{ id: 6, type: { name: "A" }, condition: "new" },{ id: 7, type: { name: "A" }, condition: "new" },{ id: 8, type: { name: "B" }, condition: "broken" },{ id: 9, type: { name: "C" }, condition: "broken" }];
let op = data.reduce( (op,inp) => {
if( op[inp.type] ){
op[inp].chunks.push(inp)
} else {
op[inp] = {
by: {...inp.type},
chunks: [inp]
}
}
return op
},{})
console.log(Object.values(op))
Voilà:
const data = [
{ id: 1, type: { name: "A" }, condition: "new" },
{ id: 2, type: { name: "C" }, condition: "broken" },
{ id: 3, type: { name: "C" }, condition: "brand new" },
{ id: 4, type: { name: "B" }, condition: "broken" },
{ id: 5, type: { name: "C" }, condition: "brand new" },
{ id: 6, type: { name: "A" }, condition: "new" },
{ id: 7, type: { name: "A" }, condition: "new" },
{ id: 8, type: { name: "B" }, condition: "broken" },
{ id: 9, type: { name: "C" }, condition: "broken" }
];
let names = [];
data.forEach(x => {
if (names.indexOf(x.type.name)==-1) {
names.push(x.type.name);
}
});
let grouped = names.map(name => ({
by: { type: {name}},
chunks: data.filter(x => x.type.name==name)
}));
console.log(grouped);
En utilisant lodash comme vous l'avez mentionné précédemment, nous pourrions le faire:
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
const data = [
{ id: 1, type: { name: "A" }, condition: "new" },
{ id: 2, type: { name: "C" }, condition: "broken" },
{ id: 3, type: { name: "C" }, condition: "brand new" },
{ id: 4, type: { name: "B" }, condition: "broken" },
{ id: 5, type: { name: "C" }, condition: "brand new" },
{ id: 6, type: { name: "A" }, condition: "new" },
{ id: 7, type: { name: "A" }, condition: "new" },
{ id: 8, type: { name: "B" }, condition: "broken" },
{ id: 9, type: { name: "C" }, condition: "broken" }
];
const groups = _.groupBy(data, (val) => val.type.name)
const formattedGroupd = Object.keys(groups).map(groupKey => {
return {
by: {type: { name: groupKey }},
chunks: groups[groupKey]
}
});
console.log(formattedGroupd)
Il vous suffit de changer la façon dont vous assignez la valeur à par dans la carte. Attribuer comme
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
const data = [
{ id: 1, type: { name: "A" }, condition: "new" },
{ id: 2, type: { name: "C" }, condition: "broken" },
{ id: 3, type: { name: "C" }, condition: "brand new" },
{ id: 4, type: { name: "B" }, condition: "broken" },
{ id: 5, type: { name: "C" }, condition: "brand new" },
{ id: 6, type: { name: "A" }, condition: "new" },
{ id: 7, type: { name: "A" }, condition: "new" },
{ id: 8, type: { name: "B" }, condition: "broken" },
{ id: 9, type: { name: "C" }, condition: "broken" }
];
console.log(_.chain(data)
.groupBy("type.name")
.map((item, i) => {
return {
by: { type: item[0].type},
chunks: item
};
})
.value())
return {
chunks: item,
by: { type: item[0].type}
};
Comme vous ne pouvez pas grouper par objet car deux objets avec les mêmes clés et valeurs ne sont pas le même objet, vous pouvez utiliser JSON.stringify () pour convertir l'objet en chaîne, et groupez-le. Utilisez Array.reduce () pour regrouper les éléments par l'objet stringifié. Convertissez en paires en utilisant Object.entries () , puis mappez les valeurs à un objet et extrayez la valeur by en utilisant JSON.parse () :
const groupByObj = (arr, key) => Object.entries(
arr.reduce((r, o) => {
const k = JSON.stringify({ [key]: o[key] });
r[k] = r[k] || [];
r[k].push(o);
return r;
}, {})
).map(([k, chunks]) => ({
by: JSON.parse(k),
chunks
}));
const data = [{"id":1,"type":{"name":"A"},"condition":"new"},{"id":2,"type":{"name":"C"},"condition":"broken"},{"id":3,"type":{"name":"C"},"condition":"brand new"},{"id":4,"type":{"name":"B"},"condition":"broken"},{"id":5,"type":{"name":"C"},"condition":"brand new"},{"id":6,"type":{"name":"A"},"condition":"new"},{"id":7,"type":{"name":"A"},"condition":"new"},{"id":8,"type":{"name":"B"},"condition":"broken"},{"id":9,"type":{"name":"C"},"condition":"broken"}];
const result = groupByObj(data, 'type');
console.log(result);
Vous pouvez utiliser reduction et Object.values pour grouper comme ceci:
const data = [{"id":1,"type":{"name":"A"},"condition":"new"},{"id":2,"type":{"name":"C"},"condition":"broken"},{"id":3,"type":{"name":"C"},"condition":"brand new"},{"id":4,"type":{"name":"B"},"condition":"broken"},{"id":5,"type":{"name":"C"},"condition":"brand new"},{"id":6,"type":{"name":"A"},"condition":"new"},{"id":7,"type":{"name":"A"},"condition":"new"},{"id":8,"type":{"name":"B"},"condition":"broken"},{"id":9,"type":{"name":"C"},"condition":"broken"}];
const merged = data.reduce((acc, o) => {
const {type} = o;
acc[type.name] = acc[type.name] || { by: { type }, chunks:[] };
acc[type.name].chunks.push(o)
return acc;
},{})
const output = Object.values(merged)
console.log(output)
(Ignorez l'extrait de code console et vérifiez la console du navigateur)
Votre réponse était la plus belle et la plus simple à lire. Cela aide aussi à résoudre mon problème et vous n'avez pas utilisé d'autres boucles pour ou conditions, ce qui est génial. Mais il ne sera pas compatible dans IE. Merci
@ DorinMusteața Je pense que toutes les réponses publiées ici utilisent certaines fonctionnalités ES6 qui ne fonctionnent pas sur IE :)
const data = [
{ id: 1, type: { name: "A" }, condition: "new" },
{ id: 2, type: { name: "C" }, condition: "broken" },
{ id: 3, type: { name: "C" }, condition: "brand new" },
{ id: 4, type: { name: "B" }, condition: "broken" },
{ id: 5, type: { name: "C" }, condition: "brand new" },
{ id: 6, type: { name: "A" }, condition: "new" },
{ id: 7, type: { name: "A" }, condition: "new" },
{ id: 8, type: { name: "B" }, condition: "broken" },
{ id: 9, type: { name: "C" }, condition: "broken" }
];
const data2 = {};
data.forEach(test => {
if (data2[test.type.name]) {
data2[test.type.name].chunks.push({
test
});
} else {
data2[test.type.name] = {
by: {
type: test.type
},
chunks: [
test
]
};
}
});
console.log(Object.values(data2));