Remove contiguous elements in array in a more functional way I try to remove elements in an array if the number of contiguous element is greater than two.

Here are the tests:

test('delete pieces if number of piece contiguous greater than two', t =&gt; {
    t.deepEqual([null, null, null], removeIdenticalPieces([1, 1, 1]));
    t.deepEqual([null, null, null, null], removeIdenticalPieces([1, 1, 1, 1]));
    t.deepEqual([null, null, null, null, 4], removeIdenticalPieces([1, 1, 1, 1, 4]));
    t.deepEqual([4, null, null, null, null], removeIdenticalPieces([4, 1, 1, 1, 1]));
    t.deepEqual([1, 1, 4, 1, 1], removeIdenticalPieces([1, 1, 4, 1, 1]));
    t.deepEqual([1, 1], removeIdenticalPieces([1, 1]));
});


Here is a working function:

function removeIdenticalPieces(line) {
    const newLine = [];
    while (line.length !== 0) {
        const firstPiece = line.shift();
        let nbContiguousPieces = 0;
        for (let i = 0; i &lt; line.length; i++) {
            let currentPiece = line[i];
            if (firstPiece !== currentPiece) {
                break;
            }
            nbContiguousPieces += 1
        }
        if (nbContiguousPieces &gt;= 2) {
            newLine.push(null);
            for (let j = 0; j &lt; nbContiguousPieces; j++) {
                line.shift();
                newLine.push(null)
            }
        } else {
            newLine.push(firstPiece);
            for (let k = 0; k &lt; nbContiguousPieces; k++) {
                newLine.push(line.shift())
            }
        }
    }
    return newLine;
}


Does a more "functional" way exist to do the same?

Edit: thank you for your solutions. 

Here the jsperf https://jsperf.com/removeidenticalpieces3.

I take the solution of @lilobase because it is faster and more readable.
One neat thing about array.reduce is that the carry doesn't need to be your resulting value. You can actually hold a record of previous runs on it by carrying an object.

I would think something along the lines of:

line.reduce((carry, current, index) =&gt; {
  // If current is same a previous, increase repeats
  // If repeats === 3, splice the last 3  in result and replace with null,
  // Else, add current to the result
  // update previous and repeats a
  // return updated carry
}, {
  result: [],
  previous: null,
  repeats: 0
}).result;