Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shorter/Better answer to "trim" an array in Javascript?

I have met a question to trim first 0s and last 0s of an array(all element is 0-9), for example,

  • for input [0, 1, 0, 2, 0], the output should be [1, 0, 2]

  • for input [1, 0, 2], the output should be [1, 0, 2]

  • for input [0, 1, 0, 2, 0, 0], the output should be [1, 0, 2]

The basic idea is to find the index of first non-zero number and the last index of non-zero index, and splice the original array.

And my way is to change the array to string and trim it, then change back to array again. trimArray=A=>A.join('').replace(/(^['0']*)|(['0']*$)/g, '').split('').map(a=>a-'0')

Is there any other ideas to do this?

like image 839
JasmineOT Avatar asked Feb 08 '23 16:02

JasmineOT


2 Answers

We can do this just using array methods...

var a = [0, 1, 0, 2, 0, 0];
while(a[0] === 0) {
    a.shift();
}

while(a[a.length - 1] === 0) {
    a.pop();
}
console.log(a)

If you need to keep the original array intact:(https://jsfiddle.net/4q0un1kp/)

function trimZeros(arr)
{
    var result = [...arr];
    while(result[0] === 0) {
        result.shift();
    }

    while(result[result.length - 1] === 0) {
        result.pop();
    }
    return result;
}

var a =  [0, 1, 0, 2, 0, 0];
var b = trimZeros(a);

alert(a);
alert(b);
like image 77
Michael Coxon Avatar answered Feb 11 '23 00:02

Michael Coxon


Keeping it super simple, we can increment and decrement borderlines for where a slice should take place from and to.

This algorithm is O(n), and has the benefit of minimal function invocations.

function trimZeros (array) {
  var front, back, length = array.length;

  if (!length) return [];

  front = 0;
  back = length - 1;

  while (array[front] === 0) front++

  if (front === length) return [];

  while (array[back] === 0) back--;

  return array.slice(front, back + 1);
}

console.log(trimZeros([0, 1, 0, 2, 0, 0]))

Alternatively, you could compose this as a method which takes a functional test, creating a more generic version. This version has bounds checking (in case of trying to trim undefined).

if (!Array.prototype.trim) {
  Array.prototype.trim = function (test) {
    var start, end, length = this.length;

    if (!length) return [];

    start = 0;
    end = length - 1;

    while (start < length && test(this[start], start)) start++;

    if (start === end) return [];

    while (end >= 0 && test(this[end], end)) end--;

    return this.slice(start, end + 1);
  }
}

console.log([0, 0, 1, 0, 2, 0, 0, 0].trim(e => e === 0));
like image 27
Oka Avatar answered Feb 11 '23 00:02

Oka