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);