TransWikia.com

Finding the first index of a sequence inside an array

Stack Overflow Asked on February 13, 2021

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]

4 Answers

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)

Correct answer by Nick on February 13, 2021

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));

Answered by sivako on February 13, 2021

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));

Answered by John on February 13, 2021

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.

Answered by Todd Rylaarsdam on February 13, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP