JavaScript数组同ID对象属性合并:需求及实现疑问
合并数组中同ID对象的属性
需求:给定一个对象数组,将所有id相同的对象合并为一个对象,合并规则是:
- 保留
id字段 - 以原对象的
prop_name作为新属性名 - 对应值取原对象
last_value.prop_value
输入示例
let array = [ {id: 'apple', prop_name: 'price_l', last_value: {id: 390897, timestamp: 1673262338, prop_value: 10}}, {id: 'orange', prop_name: 'price_g', last_value: {id: 390898, timestamp: 1673262338, prop_value: 8}}, {id: 'apple', prop_name: 'quantity_a', last_value: {id: 390899, timestamp: 1673262338, prop_value: 12}}, {id: 'orange', prop_name: 'quantity_o', last_value: {id: 390900, timestamp: 1673262338, prop_value: 14}} ];
期望输出
let array = [ {id: 'apple', price_l: 10, quantity_a: 12}, {id: 'orange', price_g: 8, quantity_o: 14} ];
你的尝试代码
function addKeyValuePair(array) { for (let i = 0; i < array.length; i++) { for (let j = i + 1; j < array.length; j++) { if (array[i].id=== array[j].id) { //I'm stuck here } } } return array; } console.log(addKeyValuePair(array));
解决方案
方法一:用reduce高效分组合并(推荐)
这种方法时间复杂度为O(n),比嵌套循环的O(n²)更高效,逻辑也更清晰:
function mergeSameIdObjects(arr) { // 用reduce创建以id为键的临时映射对象 const mergedMap = arr.reduce((map, item) => { const { id, prop_name, last_value: { prop_value } } = item; // 若当前id未在映射中,初始化带id的对象 if (!map[id]) { map[id] = { id }; } // 添加属性:prop_name作为键,prop_value作为值 map[id][prop_name] = prop_value; return map; }, {}); // 将映射对象的所有值转为数组返回 return Object.values(mergedMap); } console.log(mergeSameIdObjects(array));
方法二:基于原有嵌套循环修改
如果坚持用嵌套循环实现,需要注意数组长度变化后的索引调整:
function addKeyValuePair(array) { for (let i = 0; i < array.length; i++) { const currentItem = array[i]; for (let j = i + 1; j < array.length; j++) { if (currentItem.id === array[j].id) { // 将j元素的属性合并到i元素上 currentItem[array[j].prop_name] = array[j].last_value.prop_value; // 删除j位置的元素,同时调整索引避免跳过后续元素 array.splice(j, 1); j--; } } // 移除原对象中不需要的字段 delete currentItem.prop_name; delete currentItem.last_value; } return array; } console.log(addKeyValuePair(array));
内容的提问来源于stack exchange,提问作者Viira
相关产品推荐
相关产品推荐

