J'ai ce tableau d'objets
const arr = [{tag: 'james'},{tag: 'james'},{tag: 'john'}];
let newArr = arr.reduce((accum, arr) => {
accum[arr.tag] = ++accum[arr.tag] || 1
return accum
}, {})
console.log(newArr)Comment compter et produire un nouveau tableau comme ci-dessous?
[{
tag: 'james',
count: 2
}, {
tag: 'john',
count: 1
}]
ma tentative d'utilisation réduire l'objet produit et non le tableau d'objets.
[{
tag: 'james'
},
{
tag: 'james'
},
{
tag: 'john'
}
]
6 Réponses :
Commencez par tester si l'objet n'existe pas - si ce n'est pas le cas, créez-en un. Ajoutez ensuite à l'accumulateur. Notez également que vous voulez un tableau, utilisez donc [] et non {} pour la valeur de l'accumulateur:
.as-console-wrapper { max-height: 100% !important; top: auto; }
const data = [{
tag: 'james'
},
{
tag: 'james'
},
{
tag: 'john'
}
];
const grouped = data.reduce((acc, { tag }) => {
if (!acc.some(e => e.tag == tag)) {
acc.push({ tag, count: 0 });
}
acc.find(e => e.tag == tag).count++;
return acc;
}, []);
console.log(grouped);
Créez un objet au lieu d'un nombre et récupérez enfin ces valeurs de l'objet en utilisant Object.values méthode.
let arr = [{tag: 'james'},{tag: 'james'},{tag: 'john'}]
let ref = {};
let res = arr.reduce((accum, o) => {
ref[o.tag] || accum.push(ref[o.tag] = { ...o, count: 0 })
ref[o.tag].count++;
return accum
}, []);
console.log(res)
// an object for keeping reference
let ref = {};
let res = arr.reduce((accum, o) => {
// check reference already defined, if not define refernece and push to the array
ref[o.tag] || accum.push(ref[o.tag] = { ...o, count: 0 })
// update count using the refernece keeped in the object
ref[o.tag].count++;
return accum
}, []);
Vous pouvez même créer le tableau directement en utilisant une variable supplémentaire pour le référencement objet / index.
let arr = [{tag: 'james'},{tag: 'james'},{tag: 'john'}]
let res = Object.values(arr.reduce((accum, o) => {
accum[o.tag] = accum[o.tag] || { ...o, count: 0 }
accum[o.tag].count++;
return accum
}, {}))
console.log(res)
// just extract values from the object as an array
let res = Object.values(arr.reduce((accum, o) => {
// initialize object if not defined already
accum[o.tag] = accum[o.tag] || { ...o, count: 0 }
// increment count property
accum[o.tag].count++;
return accum
}, {}))
Vous y étiez presque, mais vous devez retirer la clé et la valeur de l'objet et créer un nouveau tableau.
.as-console-wrapper { max-height: 100% !important; top: 0; }
var array = [{ tag: 'jane' }, { tag: 'jane' }, { tag: 'john' }],
result = Object
.entries(
array.reduce((accum, { tag }) => {
accum[tag] = (accum[tag] || 0) + 1;
return accum;
}, {}))
.map(([tag, count]) => ({ tag, count }));
console.log(result);
Pourquoi la carte? Celui de Balan semble plus simple let res = Object.values (arr.reduce ((accum, o) => {accum [o.tag] = accum [o.tag] || {... o, count : 0} accum [o.tag] .count ++; return accum}, {}))
ma solution garde la surcharge petite (et abstraite) et construit un objet final, où le code métionné construit directement l'objet final comme valeur de l'objet. cela ressemble à une question de goût.
Un code plus simple serait:
const arr = [{
tag: 'james'
},
{
tag: 'james'
},
{
tag: 'john'
},
{
tag: 'lewis'
},
{
tag: 'john'
}
]
const counts = arr.reduce((acc, cv) => {
const val = acc.find(t => t.tag == cv.tag)
if (val) {
val.count++
acc.push(val)
return acc
}
cv.count = 1
acc.push(cv)
return acc
}, [])
console.log(counts)
Votre intuition était bonne et vous étiez assez proche; Je vous propose une réponse un peu plus générique
groupTags(data)("tag")
Vous pouvez l'utiliser comme
const groupTags = data => field => Object.values(data.reduce((acc, o) =>
({...acc,
[o[field]]: {
[field]: o[field],
count: acc[o[field]] ? acc[o[field]].count + 1 : 1
}
}), {}))
//simple approach using forEach method
let lists = [{tag: 'james'},{tag: 'james'},{tag: 'john'}];
const finalOutput = [];
const tempStore = {};
lists.forEach((list) => {
tempStore[list.tag] = (tempStore[list.tag] == undefined) ? 1: tempStore[list.tag]+1;
const index = finalOutput.findIndex(e => e.tag == list.tag);
if(index > -1) {
finalOutput[index] = {tag: list.tag, count: tempStore[list.tag]}
}
else
finalOutput.push({tag: list.tag, count: tempStore[list.tag]})
});
console.log(finalOutput);