如何用Lodash或原生方法合并两个对象?附替代实现思路
Let’s start with concrete sample data to make this scenario tangible—since you didn’t share exact object structures, I’ll use realistic examples that align with your described needs:
Object One (Source Items):
const objectOne = [ { id: 1, name: "Laptop", categoryId: 2 }, { id: 2, name: "Phone", categoryId: 1 }, { id: 3, name: "Tablet", categoryId: 2 } ];
Object Two (Matching Reference Data):
const objectTwo = [ { categoryId: 1, categoryName: "Mobile Devices" }, { categoryId: 2, categoryName: "Computing" } ];
Quick Context on Initial Merge Goal
If you originally wanted to merge these objects to produce a combined output like:
// Example Desired Merged Output [ { id: 1, name: "Laptop", categoryId: 2, categoryName: "Computing" }, { id: 2, name: "Phone", categoryId: 1, categoryName: "Mobile Devices" }, { id: 3, name: "Tablet", categoryId: 2, categoryName: "Computing" } ];
Here are quick solutions for that:
- Lodash:
const merged = _.map(objectOne, item => _.merge(item, _.find(objectTwo, { categoryId: item.categoryId })) ); - Native JS:
const merged = objectOne.map(item => ({ ...item, ...objectTwo.find(cat => cat.categoryId === item.categoryId) }));
Updated Approach: Traverse and Match Elements
Since you’ve shifted to needing to traverse each element in Object One and match corresponding entries in Object Two (without full merging), here’s how to implement that using nested map, find, and Lodash’s _.matches() for clean, precise matching:
Using Lodash
_.matches() creates a reusable predicate function that checks if an object matches specific properties—perfect for keeping your matching logic clean:
const matchedResults = _.map(objectOne, item => { // Create a matcher for the current item's key (e.g., categoryId) const matchPredicate = _.matches({ categoryId: item.categoryId }); // Find the corresponding entry in Object Two const matchedEntry = _.find(objectTwo, matchPredicate); // Return the structure you need (adjust based on your use case) return { ...item, matchedCategory: matchedEntry ? matchedEntry.categoryName : "No match found" }; });
Native JS Equivalent
If you prefer to avoid Lodash, you can replicate the matches logic with a custom predicate:
const matchedResults = objectOne.map(item => { const matchedEntry = objectTwo.find(cat => cat.categoryId === item.categoryId); return { ...item, matchedCategory: matchedEntry ? matchedEntry.categoryName : "No match found" }; });
Key Tips for Scalability
- Nested Objects: If your data is deeply nested (e.g., Object One has sub-items), extend this with nested
mapcalls. For example:const nestedMatched = _.map(objectOne, parentItem => ({ ...parentItem, subItems: _.map(parentItem.subItems, subItem => { const match = _.find(objectTwo, _.matches({ id: subItem.refId })); return { ...subItem, matchedData: match }; }) })); - Performance for Large Datasets: If Object Two is large, pre-create a lookup object to turn O(n*m) operations into O(n):
// Lodash version const lookup = _.keyBy(objectTwo, 'categoryId'); const fastMatched = _.map(objectOne, item => ({ ...item, matchedCategory: lookup[item.categoryId]?.categoryName || "No match found" }));
内容的提问来源于stack exchange,提问作者ajie

