如何用JavaScript ES6基于匹配ID生成分类对应新对象数组?
Great question! Ditching traditional loops for clean ES6 array methods makes this task way more readable. Let’s go with an efficient approach using a Map for fast lookups, plus spread syntax and array methods to keep things concise.
Step-by-Step Implementation
First, let’s fix a small issue in your original data: 07078 is an invalid octal literal in strict mode (which ES6 modules use by default), so we’ll use 7078 instead. Here’s the cleaned data:
const categories = [ {id: 1,name: "category 1",items: [19993, 99737]}, {id: 2,name: "category 2",items: [70264, 65474, 7078]}, {id: 3,name: "category 3",items: [76765]} ]; const items = [ {id: 19993, name: "item 1"}, {id: 70264, name: "item 2"}, {id: 99737, name: "item 3"}, {id: 65474, name: "item 4"}, {id: 76765, name: "item 5"}, {id: 7078, name: "item 6"} ];
Optimal Solution (Efficient for Large Datasets)
We’ll use a Map to create a direct lookup from item IDs to their full objects—this gives us O(1) lookup time, which is way better than looping through the entire items array for every category.
// Create a map where keys are item IDs and values are the full item objects const itemLookupMap = new Map(items.map(item => [item.id, item])); // Transform each category to replace item IDs with full objects const enrichedCategories = categories.map(category => ({ ...category, // Copy all existing category properties (id, name) items: category.items .map(itemId => itemLookupMap.get(itemId)) // Map each ID to its item object .filter(Boolean) // Optional: Remove any entries where no matching item was found })); // Log the result to verify console.log(enrichedCategories);
This will output exactly what you need:
[ {id: 1, name: "category 1", items: [{id: 19993, name: "item 1"}, {id: 99737, name: "item 3"}]}, {id: 2, name: "category 2", items: [{id: 70264, name: "item 2"}, {id: 65474, name: "item 4"}, {id: 7078, name: "item 6"}]}, {id: 3, name: "category 3", items: [{id: 76765, name: "item 5"}]} ]
Alternative (Shorter, Less Efficient for Large Data)
If your dataset is small and you want an even shorter one-liner (no Map), you can use filter directly. Just note that this loops through the entire items array for every category, which gets slow with lots of data:
const enrichedCategories = categories.map(category => ({ ...category, items: items.filter(item => category.items.includes(item.id)) }));
Key ES6 Features Used
Map: Provides fast key-value lookups.- Object Spread (
...category): Creates a shallow copy of the category object to avoid mutating the original data. Array.map(): Transforms arrays by applying a function to each element.Array.filter(): Removes any invalid/missing items (optional but safe).
内容的提问来源于stack exchange,提问作者Chicken Dinner

