JavaScript地图/减less返回按数量分组

我有一个JSON集合作为一个数组。 我想在集合中按三个字段进行分组,然后将结果与匹配文档的计数一起返回。 下面的例子将有希望更清楚。

返回的JSON文档集合:

[ { _id: 1, browser: 'chrome', ipAddress: '222.111.111.0', uri: 'example1.com' }, { _id: 2, browser: 'chrome', ipAddress: '222.111.111.0', uri: 'example1.com' }, { _id: 3, browser: 'opera', ipAddress: '222.0.888.0', uri: 'example1.com' }, { _id: 4, browser: 'chrome', ipAddress: '222.111.222.0', uri: 'sample1.com' }, { _id: 5, browser: 'chrome', ipAddress: '222.111.222.0', uri: 'sample1.com' }, { _id: 6, browser: 'chrome', ipAddress: '222.111.222.0', uri: 'sample1.com' }, { _id: 7, browser: 'opera', ipAddress: '222.111.222.0', uri: 'sample1.com' } ] 

应该在浏览器,ipAddress和uri上执行一个分组,然后返回分组结果以及下面的计数(我检查了几次,所以我希望我的数字加起来就是上面每个组合的实例!)。

 [ { browser: 'chrome', ipAddress: '222.111.111.0', uri: 'example1.com', count: 2 }, { browser: 'opera', ipAddress: '222.0.888.0', uri: 'example1.com', count: 1 }, { browser: 'chrome', ipAddress: '222.111.222.0', uri: 'sample1.com', count: 3 }, browser: 'opera', ipAddress: '222.111.222.0', uri: 'sample1.com', count: 1 ] 

我知道这应该是容易使用地图/减less可行,但我似乎无法得到我的困惑脑子如何做到这一点!

提前致谢。

使用lodash的另一个(更实用的)方法:

 _(array).groupBy(v => ([v.browser, v.ipAddress, v.uri])) .map(v => _.merge(_.omit(v[0], '_id'), {count: v.length})) .value(); 

简单的解释: groupBy使用浏览器, groupBy和uri创build一个分组。 在map语句中,我们删除_id字段,并根据组中的对象数量添加计数。

如果你打开使用lodash (如果没有,最好使用),你可以像下面这样做,

 var array = [ { _id: 1, browser: 'chrome', ipAddress: '222.111.111.0', uri: 'example1.com' }, { _id: 2, browser: 'chrome', ipAddress: '222.111.111.0', uri: 'example1.com' }, { _id: 3, browser: 'opera', ipAddress: '222.0.888.0', uri: 'example1.com' }, { _id: 4, browser: 'chrome', ipAddress: '222.111.222.0', uri: 'sample1.com' }, { _id: 5, browser: 'chrome', ipAddress: '222.111.222.0', uri: 'sample1.com' }, { _id: 6, browser: 'chrome', ipAddress: '222.111.222.0', uri: 'sample1.com' }, { _id: 7, browser: 'opera', ipAddress: '222.111.222.0', uri: 'sample1.com' } ] var res = _.reduce(array, function(acc, elem){ delete elem._id; var obj = _.find(acc, elem) if(obj){ obj.count++; } else{ elem.count = 1; acc.push(elem); } return acc; }, []) console.log(res); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script> 

你可以尝试这样的事情:

 var data=[{_id:1,browser:"chrome",ipAddress:"222.111.111.0",uri:"example1.com"},{_id:2,browser:"chrome",ipAddress:"222.111.111.0",uri:"example1.com"},{_id:3,browser:"opera",ipAddress:"222.0.888.0",uri:"example1.com"},{_id:4,browser:"chrome",ipAddress:"222.111.222.0",uri:"sample1.com"},{_id:5,browser:"chrome",ipAddress:"222.111.222.0",uri:"sample1.com"},{_id:6,browser:"chrome",ipAddress:"222.111.222.0",uri:"sample1.com"},{_id:7,browser:"opera",ipAddress:"222.111.222.0",uri:"sample1.com"}]; function groupBy(array, keys) { var groups = array.reduce(function(p, c) { var hash = keys.map(function(k){ return c[k]; }).join("|") p[hash] = p[hash] || c; p[hash]["count"] = (p[hash]["count"] || 0) + 1 delete p[hash]["_id"]; return p; }, {}); var result = Object.keys(groups).map(function(x){return groups[x] }) console.log(result); return result } var keys = ["browser", "ipAddress", "uri"] groupBy(data, keys) 

你可以使用一个简单的减法来做到这一点:

 let arr = [ { _id: 1, browser: 'chrome', ipAddress: '222.111.111.0', uri: 'example1.com' }, { _id: 2, browser: 'chrome', ipAddress: '222.111.111.0', uri: 'example1.com' }, { _id: 3, browser: 'opera', ipAddress: '222.0.888.0', uri: 'example1.com' }, { _id: 4, browser: 'chrome', ipAddress: '222.111.222.0', uri: 'sample1.com' }, { _id: 5, browser: 'chrome', ipAddress: '222.111.222.0', uri: 'sample1.com' }, { _id: 6, browser: 'chrome', ipAddress: '222.111.222.0', uri: 'sample1.com' }, { _id: 7, browser: 'opera', ipAddress: '222.111.222.0', uri: 'sample1.com' } ] let result = arr.reduce((_, x) => { for(let i = 0; i < _.length; i++) { if(_[i].browser === x.browser && _[i].ipAddress === x.ipAddress && _[i].uri === x.uri) { _[i].count++ return _ } } let { _id, ...rest } = x return [ ..._, { ...rest, count: 1 } ] }, []) console.log(result)