简体   繁体   English

使用map和reduce来获得对象数组

[英]Using map and reduce to get array of objects

I'm having an array of 我有一系列

var c = [{name: 'John'}, {name: 'John'}, {name: 'Tom'}];

I want to use the reduce method and map to get this following result: 我想使用reduce方法并映射以获得以下结果:

result = [
    { name: "John", occurence: 2 },
    { name: "Tom", occurence: 1 }
  ]

Here's an attempt I have tried but still not fully getting it. 这是我尝试过的尝试,但仍未完全解决。 https://jsfiddle.net/joeSaad/up3ddfzz/ https://jsfiddle.net/joeSaad/up3ddfzz/

 c = [{ name: 'John' }, { name: 'John' }, { name: 'Simon' }]; var d = c.reduce((countMap, word) => { countMap[word.name] = ++countMap[word.name] || 1; return countMap }, []); var e = c.reduce((countMap, word) => { q = []; countMap[word.name] = ++countMap[word.name] || 1; var p = { name: word.name, occurence: countMap[word.name] } q.push(p); return q }, []); console.log(e); 

Help much appreciated. 帮助非常感谢。 Thanks in advance 提前致谢

You're definitely on the right track working with reduce, but I would separate the computations into two distinct steps 使用reduce绝对是正确的选择,但我会将计算分为两个不同的步骤

 let c = [{name: 'John'}, {name: 'John'}, {name: 'Tom'}]; const pairs = o=> Object.keys(o).map(k=> [k, o[k]]) let count = c.reduce((acc, {name}) => { if (acc[name] === undefined) return Object.assign(acc, { [name]: 1 }) else return Object.assign(acc, { [name]: acc[name] + 1 }) }, {}) var result = pairs(count).map(([name, occurences]) => ({name, occurences})) console.log(result) //=> [ { name: 'John', occurences: 2 }, { name: 'Tom', occurences: 1 } ] 


You could abstract these behaviours into distinct functions like this 您可以将这些行为抽象为不同的函数,如下所示

 // convert an object to [[key,value]] pairs const pairs = o=> Object.keys(o).map(k=> [k, o[k]]) // count unique instances of a property value in an array of objects const countBy = (prop, xs)=> { return xs.reduce((acc, x)=> { let y = x[prop] if (acc[y] === undefined) return Object.assign(acc, { [y]: 1 }) else return Object.assign(acc, { [y]: acc[y] + 1 }) }, {}) } // your data let c = [{name: 'John'}, {name: 'John'}, {name: 'Tom'}] // then chain it all together let result = pairs(countBy('name', c)).map(([name, occurences]) => ({name, occurences})) console.log(result) //=> [ { name: 'John', occurences: 2 }, { name: 'Tom', occurences: 1 } ] 


ES6 also offers Map which is pretty good for doing this kind of computation. ES6还提供了Map ,对于执行这种计算非常有用。

This code reads a little nicer to me and is a little more semantically correct. 这段代码对我来说更好一些,在语义上也更正确一些。 Our previous code was doing the exact same thing, only it was using a plain object. 我们之前的代码做的是完全相同的事情,只是使用的是普通对象。 Map is a data structure specifically designed for this key->value data, so that makes Map a better choice. Map是专门为此key->value数据设计的数据结构,因此使Map成为更好的选择。

The only problem with this is, if your codebase isn't already using Maps in some way, introducing them just for this might be the wrong move. 唯一的问题是,如果您的代码库尚未以某种方式使用地图,则为此引入它们可能是错误的举动。

 // convert a Map to an array of pairs const mpairs = m=> [...m.entries()] // countBy this time uses Map const countBy = (prop, xs)=> { return xs.reduce((m, x)=> { let y = x[prop] if (m.has(y)) return m.set(y, m.get(y) + 1) else return m.set(y, 1) }, new Map) } // your data let c = [{name: 'John'}, {name: 'John'}, {name: 'Tom'}] // then chain it all together let result = mpairs(countBy('name', c)).map(([name, occurences]) => ({name, occurences})) console.log(result) //=> [ { name: 'John', occurences: 2 }, { name: 'Tom', occurences: 1 } ] 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM