当前位置: 代码迷 >> JavaScript >> 如何在 JavaScript/Jquery 中按数组分组
  详细解决方案

如何在 JavaScript/Jquery 中按数组分组

热度:18   发布时间:2023-06-05 10:26:35.0

我有一个如下所示的数组

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);

但我没有得到相同的格式。 有什么建议请我的想法中缺少什么? 非常感谢。

您确实可以使用按位置键控的地图,然后使用普通对象作为值。 您的代码中的问题是您将项目推入一个数组,而不是将月份值转换为单个对象(每个位置)的属性。

因此,给定一个带有普通对象的地图,迭代输入并将月份属性注入这些普通对象,并带有相应的百分比值,然后获取该地图的值:

 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);

您可以通过移交组键、键的键和收集的值来使用动态方法。

然后将所有键/值对添加到对象中,然后返回映射的值。

 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; }

另一种方法是使用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; }

一种方法是使用.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);

问题是,您不能只是重新排列对象中的属性。 根据:

ECMAScript对象是一个unordered属性集合

您可以使用您的函数重新排列属性,但无法保证最终对象中的顺序。

下面是另一个使用reduce的例子,传递回调函数并指定其中的key

 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));

  相关解决方案