如何合并对象列表中连续重复值对应的list属性?
合并对象列表中连续重复book值的list属性
我有一个对象列表,需要合并其中连续重复book值对应的list数组属性。列表里存在3个book为'B'和3个book为'A'的连续对象,只要book值连续重复,就把这些对象的list数组合并。
输入示例
let array = [ {list:[1,2,3], book:'A'}, {list:[2,1,4], book:'B'}, {list:[3,5,8], book:'A'}, {list:[4,8,5], book:'B'},// * {list:[2,8,9], book:'B'},// * {list:[6,2,7], book:'B'},// * {list:[9,7,4], book:'A'}, {list:[1,4,7], book:'B'}, {list:[1,9,3], book:'A'},// * {list:[5,2,3], book:'A'},// * {list:[7,4,2], book:'A'},// * ]
期望输出
result = [ {list:[1,2,3], book:'A'}, {list:[2,1,4], book:'B'}, {list:[3,5,8], book:'A'}, {list:[4,8,5,2,8,9,6,2,7], book:'B'},// * {list:[9,7,4], book:'A'}, {list:[1,4,7], book:'B'}, {list:[1,9,3,5,2,3,7,4,2], book:'A'},// * ]
我尝试的代码(未得到正确结果)
let array = [ {list:[1,2,3], book:'A'}, {list:[2,1,4], book:'B'}, {list:[3,5,8], book:'A'}, {list:[4,8,5], book:'B'},// * {list:[2,8,9], book:'B'},// * {list:[6,2,7], book:'B'},// * {list:[9,7,4], book:'A'}, {list:[1,4,7], book:'B'}, {list:[1,9,3], book:'A'},// * {list:[5,2,3], book:'A'},// * {list:[7,4,2], book:'A'},// * ] let A = [] let B = [] for (let x = 0; x < array.length; x++){ if( array[x].book == 'A' && array[x+1].book == 'A'){ A = A.concat(array[x].list, array[x+1].list) } else if( array[x].book == 'B' && array[x+1].book == 'B'){ B = B.concat(array[x].list, array[x+1].list) } } let adds = [] for (let x = 0; x < array.length; x++){ if( array[x].book == 'A' && array[x+1].book == 'A' ){ let A = d3.range( A[0], A[A.length-1]-1, -1) let obj = {list:A, book:'A'} adds.push(obj) } if( array[x].book == 'B' && array[x+1].book == 'B' ){ let B = d3.range( B[0], B[B.length-1]+1, 1) let obj = {price:B, trend:'B'} adds.push(obj) } if ( array[x].book == 'A' && array[x+1].book == 'B' && array[x-1].book != 'A'){ let obj = {list:array[x].list, book: 'A' } adds.push(obj) } if ( array[x].book == 'B' && array[x+1].book == 'A' && array[x-1].book != 'B' ){ let obj = {list:array[x].list, book: 'B' } adds.push(obj) } } console.log( adds )
解决方案
原代码问题分析
- 用全局
A/B数组收集所有连续重复的list,会把非连续的同book值的list混在一起,无法区分不同的连续组 - 错误使用
d3.range生成连续数值序列,完全不符合合并list的需求 - 存在属性名错误:将
list写成price,book写成trend - 循环逻辑仅处理相邻两个元素的重复,无法覆盖3个及以上的连续重复场景,还会重复添加合并后的对象
正确实现思路
遍历数组时维护一个当前合并组:
- 初始化结果数组和当前组
- 逐个遍历元素:
- 若当前组为空,直接将当前元素作为初始组
- 若当前元素的book与当前组的book一致,合并两者的list
- 若不一致,将当前组加入结果数组,再将当前元素作为新的当前组
- 遍历结束后,把最后一个当前组加入结果数组
代码实现
let array = [ {list:[1,2,3], book:'A'}, {list:[2,1,4], book:'B'}, {list:[3,5,8], book:'A'}, {list:[4,8,5], book:'B'}, {list:[2,8,9], book:'B'}, {list:[6,2,7], book:'B'}, {list:[9,7,4], book:'A'}, {list:[1,4,7], book:'B'}, {list:[1,9,3], book:'A'}, {list:[5,2,3], book:'A'}, {list:[7,4,2], book:'A'}, ]; const mergeContinuousBooks = (arr) => { if (!arr.length) return []; const result = []; // 初始化当前组:复制第一个元素的list和book,避免修改原数组 let currentGroup = { list: [...arr[0].list], book: arr[0].book }; for (let i = 1; i < arr.length; i++) { const currentItem = arr[i]; if (currentItem.book === currentGroup.book) { // 同组,合并list currentGroup.list = currentGroup.list.concat(currentItem.list); } else { // 不同组,将当前组加入结果,然后创建新组 result.push(currentGroup); currentGroup = { list: [...currentItem.list], book: currentItem.book }; } } // 把最后一个组加入结果 result.push(currentGroup); return result; }; const result = mergeContinuousBooks(array); console.log(result);
运行这段代码后,即可得到符合预期的输出。
内容的提问来源于stack exchange,提问作者Ben Davidsson
相关产品推荐
相关产品推荐

