如何在Vanilla JS或D3.js中合并不相交的对象数组?
合并两个数组(按标识匹配,缺失属性填充null)
原生JavaScript实现
这种方法不依赖第三方库,完全用原生API完成,逻辑清晰且可靠:
const A = [ { year: 2001, gdp: 1.1, population: 1100 }, { year: 2002, gdp: 1.2, population: 1200 } ]; const B = [ { year: 2000, gdp: 1.0, rainfall: 100 }, { year: 2001, gdp: 1.1, rainfall: 110 } ]; // 收集所有出现过的属性(去重) const allProperties = [...new Set([...A.flatMap(Object.keys), ...B.flatMap(Object.keys)])]; // 用Map按year聚合数据,合并同year的属性 const mergedMap = new Map(); [A, B].forEach(arr => { arr.forEach(item => { const existing = mergedMap.get(item.year) || {}; mergedMap.set(item.year, { ...existing, ...item }); }); }); // 补充缺失属性为null,并按year排序得到最终数组 const C = Array.from(mergedMap.values()) .sort((a, b) => a.year - b.year) .map(item => allProperties.reduce((acc, prop) => { acc[prop] = item[prop] ?? null; return acc; }, {})); console.log(C);
逻辑说明:
- 收集全量属性:通过
flatMap提取两个数组中所有对象的键,再用Set去重,确保最终对象包含所有出现过的属性; - 按标识聚合:用
Map以year为键存储数据,合并同一year下的所有属性(若存在重复属性,后处理的数组会覆盖前一个,这里假设同year的属性值一致); - 补全缺失值并排序:遍历聚合后的对象,给每个对象补充所有属性,缺失的属性设为
null,最后按year升序排序。
D3.js实现
如果已经在使用D3.js,利用其数据处理API可以更简洁地完成需求:
const A = [ { year: 2001, gdp: 1.1, population: 1100 }, { year: 2002, gdp: 1.2, population: 1200 } ]; const B = [ { year: 2000, gdp: 1.0, rainfall: 100 }, { year: 2001, gdp: 1.1, rainfall: 110 } ]; // 合并两个数组并按year分组 const grouped = d3.group([...A, ...B], d => d.year); // 收集所有唯一属性 const allProperties = [...new Set([...A, ...B].flatMap(Object.keys))]; // 处理分组数据,合并属性、补全缺失值并排序 const C = Array.from(grouped.entries()) .sort(([yearA], [yearB]) => yearA - yearB) .map(([year, items]) => { const mergedItem = Object.assign({}, ...items); return allProperties.reduce((acc, prop) => { acc[prop] = mergedItem[prop] ?? null; return acc; }, {}); }); console.log(C);
逻辑说明:
- 分组数据:用
d3.group直接将合并后的数组按year分组,简化聚合逻辑; - 补全属性:和原生方法一致,通过
reduce给每个对象补充所有属性,缺失值设为null; - 排序输出:将分组后的条目按
year排序,最终得到有序的合并数组。
注:你提供的示例结果中2000年的rainfall值为10,推测是笔误,代码中按输入的100处理。
内容的提问来源于stack exchange,提问作者stuwilmur
相关产品推荐
相关产品推荐

