HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

Remove contiguous elements in array in a more functional way

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
elementsarraymorewayremovecontiguousfunctional

Problem

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 => {
    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 = 2) {
            newLine.push(null);
            for (let j = 0; j < nbContiguousPieces; j++) {
                line.shift();
                newLine.push(null)
            }
        } else {
            newLine.push(firstPiece);
            for (let k = 0; k < 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.

Solution

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) => {
  // 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;

Code Snippets

line.reduce((carry, current, index) => {
  // 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;

Context

StackExchange Code Review Q#152179, answer score: 4

Revisions (0)

No revisions yet.