如何通过 lodash 对元素进行分组和计数?
How group and count elements by lodash?
我的数据:
[{
id: 1,
name: 'foo'
}, {
id: 2,
name: 'bar'
}, {
id: 1,
name: 'foo'
}
];
我想做这样的事情:
[
{
name: "foo",
id: 1,
count: 2
},
{
name: "bar",
id: 2,
count: 1
}
]
现在我按名称将 groupBy
的元素分组。
感谢您的帮助!
var source = [{
id: 1,
name: 'foo'
}, {
id: 2,
name: 'bar'
}, {
id: 1,
name: 'foo'
}
];
var result = _(source)
.groupBy('name')
.map(function(items, name) {
return {
name: name,
count: items.length
}
}).value();
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
这不完全是你要求的,但这是一个不使用 lodash 的简单方法。我在这里使用每个元素的 ID,但您可以使用任何唯一标识它的东西。
const objArray = [{
id: 1,
name: 'foo'
}, {
id: 2,
name: 'bar'
}, {
id: 1,
name: 'foo'
}
];
const reduceAndCount = (arr) => {
const newMap = {};
arr.forEach(el => {
if (!newMap[el.id]) {
el.count = 1
return newMap[el.id] = el
}
newMap[el.id].count = newMap[el.id].count + 1
})
return Object.values(newMap)
}
const result = reduceAndCount(objArray)
console.log(result)
根据上述问题的要求, 提供的答案使用 'lodash',观察到以下几点:
- 固定'groupBy'(即'name'field/column/prop)被使用
- 给出的结果包括名称和计数,但预期结果还需要 'id'。
编辑:
使用 lodash 添加解决方案,
const arrayRaw = [{
id: 1,
name: 'foo'
}, {
id: 2,
name: 'bar'
}, {
id: 1,
name: 'foo'
}];
const groupBy = (col = 'name', arr = arrayRaw) => (
_(arr).groupBy(col).map(it => ({
...it[0],
count: it.length
})).value()
);
console.log(groupBy());
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/1.2.1/lodash.min.js"></script>
如果有人需要没有 'lodash' 的解决方案,下面应该是一种可能的实现方式:
const arrayRaw = [{
id: 1,
name: 'foo'
}, {
id: 2,
name: 'bar'
}, {
id: 1,
name: 'foo'
}];
const groupBy = (col = 'name', arr = arrayRaw) => (
Object.entries(arr.reduce((fin, itm, idx) => ({
...fin,
[itm[col]]: (fin[itm[col]] || []).concat([idx])
}), {})).map(([k, v]) => ({
...arr[v[0]],
count: v.length
}))
);
console.log(groupBy());
方法/解释
这是不言自明的,但是,如果有人需要 - 请发表评论,我会补充。
我的数据:
[{
id: 1,
name: 'foo'
}, {
id: 2,
name: 'bar'
}, {
id: 1,
name: 'foo'
}
];
我想做这样的事情:
[
{
name: "foo",
id: 1,
count: 2
},
{
name: "bar",
id: 2,
count: 1
}
]
现在我按名称将 groupBy
的元素分组。
感谢您的帮助!
var source = [{
id: 1,
name: 'foo'
}, {
id: 2,
name: 'bar'
}, {
id: 1,
name: 'foo'
}
];
var result = _(source)
.groupBy('name')
.map(function(items, name) {
return {
name: name,
count: items.length
}
}).value();
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
这不完全是你要求的,但这是一个不使用 lodash 的简单方法。我在这里使用每个元素的 ID,但您可以使用任何唯一标识它的东西。
const objArray = [{
id: 1,
name: 'foo'
}, {
id: 2,
name: 'bar'
}, {
id: 1,
name: 'foo'
}
];
const reduceAndCount = (arr) => {
const newMap = {};
arr.forEach(el => {
if (!newMap[el.id]) {
el.count = 1
return newMap[el.id] = el
}
newMap[el.id].count = newMap[el.id].count + 1
})
return Object.values(newMap)
}
const result = reduceAndCount(objArray)
console.log(result)
根据上述问题的要求,
- 固定'groupBy'(即'name'field/column/prop)被使用
- 给出的结果包括名称和计数,但预期结果还需要 'id'。
编辑: 使用 lodash 添加解决方案,
const arrayRaw = [{
id: 1,
name: 'foo'
}, {
id: 2,
name: 'bar'
}, {
id: 1,
name: 'foo'
}];
const groupBy = (col = 'name', arr = arrayRaw) => (
_(arr).groupBy(col).map(it => ({
...it[0],
count: it.length
})).value()
);
console.log(groupBy());
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/1.2.1/lodash.min.js"></script>
如果有人需要没有 'lodash' 的解决方案,下面应该是一种可能的实现方式:
const arrayRaw = [{
id: 1,
name: 'foo'
}, {
id: 2,
name: 'bar'
}, {
id: 1,
name: 'foo'
}];
const groupBy = (col = 'name', arr = arrayRaw) => (
Object.entries(arr.reduce((fin, itm, idx) => ({
...fin,
[itm[col]]: (fin[itm[col]] || []).concat([idx])
}), {})).map(([k, v]) => ({
...arr[v[0]],
count: v.length
}))
);
console.log(groupBy());
方法/解释 这是不言自明的,但是,如果有人需要 - 请发表评论,我会补充。