Search code examples
javascriptarraysobjectmerge

How can I merge consecutive repeated values in list of objects?


I have a list of objects, and I want to merge consecutive repeated values.

In this list of objects we have three values of (B) and three values of (A). If the values are repeated and consecutive, I want to merge the existing list at {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'},// *
]

The result will be like this:

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'},// *
]

and Thank you in advance.

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 )


Solution

  • I think you've made this more complicated then it has to be, here is my approach (I've probably did that as well):

    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 result = [];
    
    for (let i = 0; i < array.length; i++) {
      if (i === 0) {
        result.push(array[i]);
      } else if (array[i].book === result[result.length - 1].book) {
        result[result.length - 1].list.push(...array[i].list);
      } else {
        result.push(array[i]);
      }
    }
    
    
    console.log(result);

    The main part of this approach is this check array[i].book === result[result.length - 1].book. What this does is to check if the book property of the element from array at the current iteration is the same as the last one from the result array.

    The rest is just adding the element at the current iteration to result. When result is empty (first iteration) or when the condition that I've mentioned before isn't meet.