1

In this function I count the number of consecutive zeros that should be at least of length zerosMin. Is there any way I could return the first index of the start of the sequences? For example, for arr = [1,0,0,0,0,0,1,0,0,0,0] it would be [1,7]

function SmallestBlockOfZeros(arr, zerosMin) {
    let result = [];
    let counter = 1;

    for (let i = 0; i < arr.length; i++) {
        if (arr[i] == 0) {
            if (arr[i] === arr[i + 1]) {
                counter++;
            } else if (counter >= zerosMin) {
                result.push(counter);

                counter = 1;
            } else {
                counter = 1;
            }
        }
    }
    return result;
}
let arr = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0];
let zerosMin = 4;

console.log(SmallestBlockOfZeros(arr, zerosMin));
//Console output : [5,4]
Hao Wu
  • 17,573
  • 6
  • 28
  • 60

4 Answers4

1

You can iterate through the array, pushing an index into the result array whenever you encounter a block of 0 values that is at least zerosMin long, and then skipping all those 0 values until you find the next non-0 value or pass the point at which a zerosMin string of 0s could occur:

let arr = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0];
let zerosMin = 4;

let zeroStarts = [];
for (let i = 0; i <= arr.length - zerosMin; i++) {
  if (arr.slice(i, i + zerosMin).filter(Boolean).length == 0) {
    zeroStarts.push(i);
    i += zerosMin;
    while (i <= arr.length - zerosMin && arr[i] == 0) {
      i++;
    }
  }
}
console.log(zeroStarts);

Note I've used filter(Boolean) because 0 is falsey; if you were searching for a run of non-zero values you would use something like filter(v => v != 0)

Nick
  • 138,499
  • 22
  • 57
  • 95
1

If you don't need to actually iterate elements, you can use a shortcut

function foo(arr, min)
{
  let el = arr.join("").match(new RegExp('0{' + min + ',}'));
  
  return [el.index, el.index + el[0].length];
}

console.log(foo([1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0], 3));
John
  • 5,942
  • 3
  • 42
  • 79
0

For start of each chain of zeros:

function indexOfValue(arr, val) {
    var indexes = [], i;
    for(i = 0; i < arr.length; i++)
        if (arr[i] === val)
            indexes.push(i);
    return indexes;
}

(see How to find index of all occurrences of element in array?)

The code you posted above appears to work for length of blocks of 0s.

Todd Rylaarsdam
  • 438
  • 6
  • 19
0

While iterating the items, keep track of last non-zero index and push the index to output array when criteria matches.

const SmallestBlockOfZeros = (arr, zerosMin) => {
  let index = 0;
  const output = [];
  for (let i = 0; i <= arr.length; i++) {
    if (arr[i] !== 0 || !(i in arr)) {
      i - index - 1 >= zerosMin && output.push(index + 1);
      index = i;
    }
  }
  return output;
};

const arr = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0];
const zerosMin = 4;
console.log(SmallestBlockOfZeros(arr, zerosMin));
Siva K V
  • 10,561
  • 2
  • 16
  • 29