如何合并两个多维对象并实现元素去重?寻求技术解决方案
Solution for Merging Nested Object Arrays (Union with Deduplication)
Got it, let's work through this nested merging problem. The core challenge here is handling the multi-level hierarchy: we need to match parent nodes by their text property, recursively merge their child arrays, and finally deduplicate the deepest child nodes using their unique id.
Step-by-Step Approach
- Group Parent Nodes: Use a
Mapto track nodes by theirtextvalue—this helps avoid duplicate parent nodes across the two input arrays. - Recursive Child Merging: For any existing parent node, recursively merge its
childrenarray with the corresponding node from the other input. - Deepest Node Deduplication: For the lowest-level nodes (those with an
idand nochildren), remove duplicates by checking the uniqueidproperty.
Implementation Code
function mergeNestedArrays(arr1, arr2) { // Map to store nodes grouped by their 'text' property const mergedMap = new Map(); // Helper to process each array and populate the map const processNodes = (nodes) => { nodes.forEach(node => { if (mergedMap.has(node.text)) { // If node exists, recursively merge its children const existingNode = mergedMap.get(node.text); if (node.children && existingNode.children) { existingNode.children = mergeNestedArrays(existingNode.children, node.children); } } else { // Deep copy to avoid mutating original objects mergedMap.set(node.text, JSON.parse(JSON.stringify(node))); } }); }; // Process both input arrays processNodes(arr1); processNodes(arr2); // Helper to deduplicate deepest nodes by 'id' const deduplicateLeafNodes = (nodes) => { return nodes.reduce((acc, current) => { if (current.children) { // Recurse into children if they exist acc.push({ ...current, children: deduplicateLeafNodes(current.children) }); } else { // Only add if no existing node with the same id const duplicate = acc.find(node => node.id === current.id); if (!duplicate) { acc.push(current); } } return acc; }, []); }; // Convert map values to array and deduplicate leaf nodes return deduplicateLeafNodes(Array.from(mergedMap.values())); } // Test with your source data const data_1 = [{ text: 'A', children: [{ text: 'B', children: [{ text: 'C', children: [ {text: 'B [43]', id: '43'}, {text: 'B [11]', id: '11'}, ]} ]} ] }, { text: 'W', children: [ { text: 'M', children: [{ text: 'K', children: [{text: 'M [48]', id: '48'}] }] }, { text: 'T', children: [{ text: 'K', children: [{text: 'S [78]', id: '78'}] }] } ] } ]; const data_2 = [{ text: 'A', children: [{ text: 'B', children: [{ text: 'C', children: [ {text: 'B [93]', id: '93'}, {text: 'B [11]', id: '11'}, ]} ]} ] }, { text: 'D', children: [{ text: 'M', children: [{ text: 'N', children: [ {text: 'M [66]', id: '66'} ]} ] }] }, { text: 'W', children: [{ text: 'M', children: [{ text: 'K', children: [ {text: 'M [58]', id: '58'} ] }] }] } ]; const finalMergedData = mergeNestedArrays(data_1, data_2); console.log(JSON.stringify(finalMergedData, null, 2));
Key Notes
- Deep Copy: We use
JSON.parse(JSON.stringify(node))to create a deep copy of nodes, preventing unintended mutations to your original source data. If your nodes contain non-serializable values (like functions), you'll need a custom deep copy function instead. - Custom Identifiers: If
textisn't the unique identifier for parent nodes in your actual data, just adjust theMapkey to use the correct unique property. - Extensibility: If your nodes have additional properties beyond
text,children, andid, you can modify the merging logic to include those (e.g., usingObject.assignto merge properties of existing nodes).
内容的提问来源于stack exchange,提问作者Tomas
相关产品推荐
相关产品推荐

