如何根据对象数组中的值动态创建分组数组?
Hey there! Let's tackle this dynamic grouping problem you're working on. From what I can tell, you need to group objects in an array based on flexible, changing conditions—where objects matching the same condition get lumped into the same sub-array, and new sub-arrays are created automatically whenever a new condition match pops up. Even with 200+ objects, we can make this efficient and adaptable.
Core Approach: Dynamic Grouping with a Key Generator
The most flexible way to solve this is to use a custom key-generating function that defines how we group objects. This function will take an object from your array and return a unique "group key"—any objects with the same key get grouped together. We can then use reduce (or a Map for more complex keys) to build our grouped array.
Implementation Example
Let's start with a solution tailored to your sample input, then show how to adapt it for any condition.
Step 1: Define Your Grouping Logic
First, write a function that generates a group key for each object. For your sample, objects are grouped by the hundreds place of points.x (100-199 = group 1, 200-299 = group 2):
const getGroupKey = (obj) => { // Split x values into hundreds-based groups return Math.floor(obj.points.x / 100); };
Step 2: Use reduce to Build Groups
We'll use Array.reduce() to iterate through the array and organize objects into groups:
const array = [ { name: 'A', age: '', points: { x: 100, y: 107} }, { name: 'B', age: '', points: { x: 210, y: 107} }, { name: 'C', age: '', points: { x: 110, y: 107} }, { name: 'D', age: '', points: { x: 230, y: 107} } ]; const groupedArray = Object.values( array.reduce((groupMap, currentObj) => { const key = getGroupKey(currentObj); // Create a new group if this key doesn't exist yet if (!groupMap[key]) { groupMap[key] = []; } // Add the current object to its group groupMap[key].push(currentObj); return groupMap; }, {}) // Initialize with an empty object to hold groups ); console.log(groupedArray); // Output matches your expected result exactly!
Make It Reusable & Flexible
To handle any dynamic condition, wrap the logic into a reusable function. This way you just swap out the key generator whenever your grouping rules change:
function groupByDynamicCondition(arr, getGroupKey) { return Object.values( arr.reduce((groupMap, item) => { const key = getGroupKey(item); groupMap[key] = groupMap[key] || []; groupMap[key].push(item); return groupMap; }, {}) ); } // Example 1: Group by points.y value const groupedByY = groupByDynamicCondition(array, (obj) => obj.points.y); // Example 2: Group by custom x ranges (0-150, 151-300) const groupedByXRange = groupByDynamicCondition(array, (obj) => { if (obj.points.x <= 150) return 'low-x'; return 'high-x'; });
Handling Complex Group Keys
If your grouping condition relies on complex values (like objects), use a Map instead of a plain object to avoid stringification issues:
function groupByComplexCondition(arr, getGroupKey) { const groupMap = new Map(); arr.forEach(item => { const key = getGroupKey(item); if (!groupMap.has(key)) { groupMap.set(key, []); } groupMap.get(key).push(item); }); return Array.from(groupMap.values()); } // Example: Group by combined points.x range and points.y const groupedByCombined = groupByComplexCondition(array, (obj) => { const xRange = obj.points.x < 200 ? 'low' : 'high'; // Return an array as the key (Map supports non-string keys) return [xRange, obj.points.y]; });
Why This Works
- Efficiency: Runs in O(n) time (where n is the number of objects), so it handles 200+ items easily with no performance hits.
- Flexibility: Just update the
getGroupKeyfunction to match any new grouping rules—no need to rewrite the core grouping logic. - Automatic New Groups: Any object with a new key will trigger a new sub-array, exactly as you need.
内容的提问来源于stack exchange,提问作者Connect2sky

