如何对指定JavaScript数组进行分组或汇总?
Hey there! Let's break down how to group or aggregate your JavaScript array based on shared properties like name, family, or caseID—here are a few solid, practical approaches you can use:
First, let's fix the small syntax error in your original array (the last object was missing an opening {):
var json = [ { id: 11, name:"app1", family:"apps", caseID: 123, order:1 }, { id: 12, name:"app1", family:"apps", caseID: 123, order:2 }, { id: 13, name:"app1", family:"apps", caseID: 123, order:3 }, { id: 14, name:"app2", family:"tools", caseID: 129, order:1 }, { id: 15, name:"app2", family:"tools", caseID: 129, order:2 }, { id: 16, name:"app3", family:"utils", caseID: 120, order:1 }, { id: 17, name:"app3", family:"utils", caseID: 120, order:2 }, { id: 18, name:"app3", family:"utils", caseID: 150, order:1 } ];
Array.reduce() (Most Recommended for Vanilla JS) This is the go-to approach for grouping/aggregating without external dependencies. It lets you build a grouped object step by step.
Group by a single property (e.g., caseID)
const groupedByCaseID = json.reduce((accumulator, currentItem) => { // Use caseID as the grouping key const key = currentItem.caseID; // Initialize an empty array for the key if it doesn't exist if (!accumulator[key]) { accumulator[key] = []; } // Add the current item to the corresponding group accumulator[key].push(currentItem); return accumulator; }, {}); console.log(groupedByCaseID); // Output will have keys like 123, 129, 120, 150, each holding an array of matching items
Group by multiple properties (e.g., name + caseID)
If you need to group items that share both a name and caseID (like app3's separate caseID 120 and 150), combine properties into a unique key:
const groupedByNameAndCaseID = json.reduce((acc, item) => { const uniqueKey = `${item.name}-${item.caseID}`; if (!acc[uniqueKey]) { acc[uniqueKey] = []; } acc[uniqueKey].push(item); return acc; }, {});
Aggregate data (e.g., collect orders + count items per group)
If you want to summarize instead of just grouping, build custom aggregated objects:
const aggregatedSummary = json.reduce((acc, item) => { const key = item.caseID; if (!acc[key]) { // Initialize a summary object for the group acc[key] = { name: item.name, family: item.family, caseID: item.caseID, orderList: [], totalItems: 0 }; } // Add details to the summary acc[key].orderList.push(item.order); acc[key].totalItems++; return acc; }, {}); // Convert the summary object to an array if needed const aggregatedArray = Object.values(aggregatedSummary); console.log(aggregatedArray);
Map Object If you prefer working with Map (great for preserving key types or more flexible key handling), this works too:
const groupMap = new Map(); json.forEach(item => { const key = item.caseID; if (!groupMap.has(key)) { groupMap.set(key, []); } groupMap.get(key).push(item); }); // Convert Map to a plain object if needed const groupedByMap = Object.fromEntries(groupMap);
groupBy (If You're Already Using Lodash) If your project already includes Lodash, this cuts down on boilerplate code significantly:
// Make sure Lodash is imported: import _ from 'lodash'; // Group by single property const groupedByCaseID = _.groupBy(json, 'caseID'); // Group by multiple properties const groupedByNameAndCaseID = _.groupBy(json, item => `${item.name}-${item.caseID}`);
Quick Notes
- Use
reduceif you want full control and no external dependencies. - Use
Mapif you need non-string keys or want to leverage Map's built-in methods. - Use Lodash only if it's already part of your project (no need to add it just for grouping).
内容的提问来源于stack exchange,提问作者Ray

