How to create windowed slice of array in javascrip

2020-05-09 19:04发布

问题:

I'm looking for an array method implementation named Array.window(n) that invoked on an array with parameter n, would give a contiguous overlapping array slice.

Example:

let a = [1, 2, 3, 4, 5, 6]
a.window(2) // [[1, 2], [2, 3], [3, 4], [4, 5], [5, 6]]
a.window(3) // [[1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 6]]
a.window(4) // [[1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6]]
a.window(10)// []

How can I accomplish this?

回答1:

Here you go with a slightly shorter example using array functions:

let a = [1, 2, 3, 4, 5, 6];
function windowedSlice(arr, size) {
    let result = [];
    arr.some((el, i) => {
        if (i + size >= arr.length) return true;
        result.push(arr.slice(i, i + size));
    });
    return result;
}
console.log(windowedSlice(a, 2));
console.log(windowedSlice(a, 3));
console.log(windowedSlice(a, 4));
console.log(windowedSlice(a, 5));


回答2:

I think this would suffice:

function arrayWindow(array, n) {
  if (array.length < n || n <= 0) {
    return []
  }

  let arrayLength = array.length
  let result = []
  for (let i = 0; i < arrayLength; i++) {
    let slicedArray = array.slice(i, n+i)
    if (slicedArray && slicedArray.length === n) {
      result.push(slicedArray)
      continue
    }
    break
  }
  return result
}

let arr = [1, 2, 3, 4, 5, 6]
console.log(arrayWindow(arr, 2))
console.log(arrayWindow(arr, 3))
console.log(arrayWindow(arr, 4))
console.log(arrayWindow(arr, 5))
console.log(arrayWindow(arr, 10))
console.log(arrayWindow(arr, 0))



回答3:

Here is a simple rolling window function. Notice that we can determine the number of iterations based on array length minus the desired window size.

/**
 * Produces a rolling window of desired length {w} on a 1d array.
 * 
 * @param {Array} a The 1d array to window.
 * @param {Number} w The desired window size.
 * @return {Array} A multi-dimensional array of windowed values.
 */
function rolling(a, w) {
    let n = a.length;
    let result = [];

    if (n < w || w <= 0) {
        return result;
    }

    for (let i = 0; i < n - w + 1; i++) {
        result.push(a.slice(i, w + i));
    }

    return result;
}

let a = [1, 2, 3, 4, 5];
console.log(JSON.stringify(rolling(a, 3)));