我有一个如下数组
array1 = [{"month":"January","location":"CENTRAL","percentage":94},
{"month":"February","location":"CENTRAL","percentage":97},
{"month":"March","location":"CENTRAL","percentage":93},
{"month":"January","location":"NORTH","percentage":95},
{"month":"February","location":"NORTH","percentage":91},
{"month":"March","location":"NORTH","percentage":98}];
我想格式化数组,使其如下所示
array2= [{
location: "CENTRAL",
January: 94,
February: 97,
March: 93},
{
location: "NORTH",
January: 95,
February: 91,
March: 98}];
我试图按以下功能使用分组功能
function groupBy(list, keyGetter) {
const map = new Map();
list.forEach((item) => {
const key = keyGetter(item);
if (!map.has(key)) {
map.set(key, [item]);
} else {
map.get(key).push(item);
}
});
return map;
}
const grouped = groupBy(array1, arr => arr.location);
console.log(grouped);
但是我没有得到相同的格式。有什么建议可以帮助我解决我的想法吗?非常感谢。
答案 0 :(得分:3)
您确实可以使用按位置作为键的地图,但是可以将普通对象用作值。代码中的问题是,您将项目推入数组,并且不将month值转换为单个对象的属性(按位置)。
因此,给定一个包含普通对象的地图,请迭代输入,并将月属性插入具有相应百分比值的那些普通对象中,然后获取该地图的值:
const array1 = [{"month":"January","location":"CENTRAL","percentage":94},{"month":"February","location":"CENTRAL","percentage":97},{"month":"March","location":"CENTRAL","percentage":93},{"month":"January","location":"NORTH","percentage":95},{"month":"February","location":"NORTH","percentage":91},{"month":"March","location":"NORTH","percentage":98}];
const map = new Map(array1.map(({location}) => [location, { location }]));
array1.forEach(o => map.get(o.location)[o.month] = o.percentage);
const result = [...map.values()];
console.log(result);
答案 1 :(得分:3)
一种替代方法是使用函数reduce
按location
进行分组,并使用函数Object.values
提取分组的对象。
let array1 = [{"month":"January","location":"CENTRAL","percentage":94},{"month":"February","location":"CENTRAL","percentage":97},{"month":"March","location":"CENTRAL","percentage":93},{"month":"January","location":"NORTH","percentage":95},{"month":"February","location":"NORTH","percentage":91},{"month":"March","location":"NORTH","percentage":98}],
groupBy = (array, keygetter) => {
return Object.values(array1.reduce((a, {month, percentage, ...rest}) => {
let key = keygetter(rest);
(a[key] || (a[key] = {location: key}))[month] = percentage;
return a;
}, Object.create(null)));
},
result = groupBy(array1, (o) => o.location);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
答案 2 :(得分:2)
您可以通过传递组密钥,密钥和收集值来使用动态方法。
然后将所有键/值对添加到对象,然后返回映射的值。
function groupBy(list, group, key, value) {
return Array.from(list
.reduce((map, object) => map.set(object[group], Object.assign(
map.get(object[group]) || { [group]: object[group] },
{ [object[key]]: object[value] }
)), new Map)
.values()
);
}
var array = [{ month: "January", location: "CENTRAL", percentage: 94 }, { month: "February", location: "CENTRAL", percentage: 97 }, { month: "March", location: "CENTRAL", percentage: 93 }, { month: "January", location: "NORTH", percentage: 95 }, { month: "February", location: "NORTH", percentage: 91 }, { month: "March", location: "NORTH", percentage: 98 }],
result = groupBy(array, 'location', 'month', 'percentage');
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
答案 3 :(得分:2)
一种方法是使用.filter()
和.map()
var array1 = [{"month":"January","location":"CENTRAL","percentage":94},
{"month":"February","location":"CENTRAL","percentage":97},
{"month":"March","location":"CENTRAL","percentage":93},
{"month":"January","location":"NORTH","percentage":95},
{"month":"February","location":"NORTH","percentage":91},
{"month":"March","location":"NORTH","percentage":98}];
const groupBy = (arr, prop, propName1, propName2, propName3) =>
Object.assign({[prop]:propName1}
, ...arr.filter(({[prop]:p}) => p === propName1)
.map(({[propName2]:m, [propName3]:p}) => ({[m]: p}))
);
const locations = ["CENTRAL", "NORTH"];
let res = locations.map(prop => groupBy(array1, "location", prop, "month", "percentage"));
console.log(res);
答案 4 :(得分:0)
问题是,您不能只是重新排列对象中的属性。根据{{3}}:
ECMAScript 对象是{strong>属性
的unordered
集合
您可以使用函数重新排列属性,但是不能保证最终对象中的顺序。
答案 5 :(得分:0)
这是另一个使用reduce的示例,传递回调函数并在其中指定键
array1 = [{
"month": "January",
"location": "CENTRAL",
"percentage": 94
},
{
"month": "February",
"location": "CENTRAL",
"percentage": 97
},
{
"month": "March",
"location": "CENTRAL",
"percentage": 93
},
{
"month": "January",
"location": "NORTH",
"percentage": 95
},
{
"month": "February",
"location": "NORTH",
"percentage": 91
},
{
"month": "March",
"location": "NORTH",
"percentage": 98
}
];
function groupBy(list, callback) {
return list.reduce((acc, x) => {
const key = callback(x);
if (!acc[key]) {
return {
...acc,
[key]: [x]
}
}
return {
...acc,
[key]: [...acc[key], x]
}
}, {})
}
// callback function
function locationName(obj) {
return obj.location
}
console.log('group by location name:', groupBy(array1, locationName));