对数组中的项目进行分组和计数的简洁方法
Concise way to Group by and Count item in array
我有一个这样的数组:
const arr = [ {name: 'Server 1', country: 'DE'}, {name: 'Server 2', country: 'PL'},
{name: 'Server 3', country: 'US'}, {name: 'Server 4', country: 'DE'},
{name: 'Server 5', country: 'US'}];
我想要的是 group and count
得到如下 输出:
[
{
"country": "DE",
"count": 2
},
{
"country": "PL",
"count": 1
},
{
"country": "US",
"count": 2
}
]
目前,我正在使用 lodash
,但我认为有更好的方法 (例如,使用 _groupBy
或其他方法像那样) 来解决吧?
我的代码在这里:
const arr = [ {name: 'Server 1', country: 'DE'}, {name: 'Server 2', country: 'PL'}, {name: 'Server 3', country: 'US'}, {name: 'Server 4', country: 'DE'}, {name: 'Server 5', country: 'US'}];
const objectGroupby = _.countBy(arr, 'country');
const result = Object.entries(objectGroupby).map(([key, value]) => ({country: key, count: value}));
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>
如您所见,_.countBy(arr, 'country')
只是returns一个对象而不是数组。
{
"DE": 2,
"PL": 1,
"US": 2
}
那我就得用Object.entries()
&map
来解决了
就性能而言,我认为我可以使用简单的 for loops as for loops are faster than .map(), .reduce() 等来编写性能更高的代码
只需要遍历一次原数组即可,
const arr = [ {name: 'Server 1', country: 'DE'}, {name: 'Server 2', country: 'PL'}, {name: 'Server 3', country: 'US'}, {name: 'Server 4', country: 'DE'}, {name: 'Server 5', country: 'US'}];
let mapObj = {};
let res = [];
let resIndex = 0;
for(let i = 0; i < arr.length; i++) {
if(mapObj[arr[i].country] >= 0) {
res[mapObj[arr[i].country]].count++;
} else {
res.push({country: arr[i].country, count: 1});
mapObj[arr[i].country] = resIndex;
resIndex++;
}
}
console.log(res);
就优雅或更易读的代码而言,我认为使用 reduce 更具可读性。但可读性是主观的,因人而异。对我来说 reduce 会更具可读性。
const arr = [ {name: 'Server 1', country: 'DE'}, {name: 'Server 2', country: 'PL'}, {name: 'Server 3', country: 'US'}, {name: 'Server 4', country: 'DE'}, {name: 'Server 5', country: 'US'}];
res = arr.reduce((prev, curr) => {
const index = prev.findIndex(item => item.country === curr.country);
if(index > -1) {
prev[index].count++;
} else {
prev.push({ country: curr.country, count: 1});
}
return prev;
}, []);
console.log(res);
更新:
使用 Lodash,
const arr = [ {name: 'Server 1', country: 'DE'}, {name: 'Server 2', country: 'PL'}, {name: 'Server 3', country: 'US'}, {name: 'Server 4', country: 'DE'}, {name: 'Server 5', country: 'US'}];
result = _.reduce(_.countBy(arr, 'country'), (result, value, key) => {
result.push({ country: key, count: value});
return result;
}, []);
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>
万岁!!!
经过这几天的研究,我终于找到了这样的解决方法groupBy
。
const arr = [ {name: 'Server 1', country: 'DE'}, {name: 'Server 2', country: 'PL'}, {name: 'Server 3', country: 'US'}, {name: 'Server 4', country: 'DE'}, {name: 'Server 5', country: 'US'}];
const result = _(arr).groupBy(x => x.country)
.map((value, key) => ({country: key, count: value.length}));
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>
说明:
- 第一步:根据
country
属性 对数组元素进行分组
- 第 2 步:使用具有 2 个参数值的 .map:
key
是组的名称(国家/地区),value
是对象数组。
参考资源:
- using lodash .groupBy. how to add your own keys for grouped output?
我有一个这样的数组:
const arr = [ {name: 'Server 1', country: 'DE'}, {name: 'Server 2', country: 'PL'},
{name: 'Server 3', country: 'US'}, {name: 'Server 4', country: 'DE'},
{name: 'Server 5', country: 'US'}];
我想要的是 group and count
得到如下 输出:
[
{
"country": "DE",
"count": 2
},
{
"country": "PL",
"count": 1
},
{
"country": "US",
"count": 2
}
]
目前,我正在使用 lodash
,但我认为有更好的方法 (例如,使用 _groupBy
或其他方法像那样) 来解决吧?
我的代码在这里:
const arr = [ {name: 'Server 1', country: 'DE'}, {name: 'Server 2', country: 'PL'}, {name: 'Server 3', country: 'US'}, {name: 'Server 4', country: 'DE'}, {name: 'Server 5', country: 'US'}];
const objectGroupby = _.countBy(arr, 'country');
const result = Object.entries(objectGroupby).map(([key, value]) => ({country: key, count: value}));
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>
如您所见,_.countBy(arr, 'country')
只是returns一个对象而不是数组。
{
"DE": 2,
"PL": 1,
"US": 2
}
那我就得用Object.entries()
&map
来解决了
就性能而言,我认为我可以使用简单的 for loops as for loops are faster than .map(), .reduce() 等来编写性能更高的代码
只需要遍历一次原数组即可,
const arr = [ {name: 'Server 1', country: 'DE'}, {name: 'Server 2', country: 'PL'}, {name: 'Server 3', country: 'US'}, {name: 'Server 4', country: 'DE'}, {name: 'Server 5', country: 'US'}];
let mapObj = {};
let res = [];
let resIndex = 0;
for(let i = 0; i < arr.length; i++) {
if(mapObj[arr[i].country] >= 0) {
res[mapObj[arr[i].country]].count++;
} else {
res.push({country: arr[i].country, count: 1});
mapObj[arr[i].country] = resIndex;
resIndex++;
}
}
console.log(res);
就优雅或更易读的代码而言,我认为使用 reduce 更具可读性。但可读性是主观的,因人而异。对我来说 reduce 会更具可读性。
const arr = [ {name: 'Server 1', country: 'DE'}, {name: 'Server 2', country: 'PL'}, {name: 'Server 3', country: 'US'}, {name: 'Server 4', country: 'DE'}, {name: 'Server 5', country: 'US'}];
res = arr.reduce((prev, curr) => {
const index = prev.findIndex(item => item.country === curr.country);
if(index > -1) {
prev[index].count++;
} else {
prev.push({ country: curr.country, count: 1});
}
return prev;
}, []);
console.log(res);
更新: 使用 Lodash,
const arr = [ {name: 'Server 1', country: 'DE'}, {name: 'Server 2', country: 'PL'}, {name: 'Server 3', country: 'US'}, {name: 'Server 4', country: 'DE'}, {name: 'Server 5', country: 'US'}];
result = _.reduce(_.countBy(arr, 'country'), (result, value, key) => {
result.push({ country: key, count: value});
return result;
}, []);
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>
万岁!!!
经过这几天的研究,我终于找到了这样的解决方法groupBy
。
const arr = [ {name: 'Server 1', country: 'DE'}, {name: 'Server 2', country: 'PL'}, {name: 'Server 3', country: 'US'}, {name: 'Server 4', country: 'DE'}, {name: 'Server 5', country: 'US'}];
const result = _(arr).groupBy(x => x.country)
.map((value, key) => ({country: key, count: value.length}));
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>
说明:
- 第一步:根据
country
属性 对数组元素进行分组
- 第 2 步:使用具有 2 个参数值的 .map:
key
是组的名称(国家/地区),value
是对象数组。
参考资源:
- using lodash .groupBy. how to add your own keys for grouped output?