Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove adjacent duplicates on array

Suppose we have an array of numbers like the next one:

const input = [2, 2, 0, 2, 3, 3, 0, 0, 1, 1];

The goal is to remove duplicates values, but only if they are adjacent. So, the expected output for the previous sample should be:

[2, 0, 2, 3, 0, 1]

So far, I managed to almost solve this using a recursive approach, but for some reason that I can't figure, the generated result is not returned (however, you can see it on the log before the returning condition).

const input = [2, 2, 0, 2, 3, 3, 0, 0, 1, 1];

const remAdjDups = (arr, output = []) =>
{
    if (!arr.length)
    {
        console.log("Result before return: ", output);
        return output;
    }

    if (arr[0] === arr[1])
    {
        arr.splice(1, 1);
        remAdjDups(arr, output);
    }
    else
    {
        remAdjDups(arr.slice(1), output.concat(arr[0]));
    }
}

let out = remAdjDups(input.slice());
console.log("output: ", out);
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}

So, first and mainly, I will like to understand what is happening with my approach, and second I'm open to any other approach (of any type) that could solve this problem.


Updated Solution

Just in case anyone is interested, I have finally solve this problem using recursion this way. I know filter solution is shorted and elegant, but I was training solving by recursion.

const input = [2, 2, 0, 2, 3, 3, 0, 0, 1, 1, 1, 1, 1];

const remAdjDups = ([x, y, ...rest], out = []) =>
{
    if (!rest.length)
        return (x === y) ? [...out, x] : [...out, x, y];
    else if (x === y)
        return remAdjDups([x, ...rest], out);
    else
        return remAdjDups([y, ...rest], [...out, x]);
}

let out = remAdjDups(input.slice());
console.log("output: ", out);
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}
like image 397
Shidersz Avatar asked Feb 09 '19 05:02

Shidersz


2 Answers

Regarding your solution, just add return before remAdjDups(arr...

P.S.

I used Array.prototype.filter for that

const input = [2, 2, 0, 2, 3, 3, 0, 0, 1, 1];

const result = input.filter((i,idx) => input[idx-1] !== i)

console.log(result)
like image 126
Nurbol Alpysbayev Avatar answered Sep 18 '22 02:09

Nurbol Alpysbayev


You can use filter

const input = [2, 2, 0, 2, 3, 3, 0, 0, 1, 1];

const result = input.filter((i,index) => {
 if(index != 0){
  return input[index-1] !== i
 } 
 return i
})

console.log(result)
like image 27
Code Maniac Avatar answered Sep 18 '22 02:09

Code Maniac