There is a great question on how to split a JavaScript array into chunks. I'm currently using this for some statistical methods I'm writing and the answer that I'm using is as follows (although I chose not to extend the Array prototype like they did in the answer):

var chunk = function(array, chunkSize) {
    return [].concat.apply([],
        array.map(function(elem,i) {
            return i%chunkSize ? [] : [array.slice(i,i+chunkSize)];
        })
    );
};

This takes an array, such as [1,2,3,4,5,6], and given a chunkSize of 2 returns [[1,2],[3,4],[5,6]]. I'm curious how I could modify this to create an array of "overlapping" chunks (or for those familiar with methods such as a moving average, "moving subgroups").

Provided the same array as above and chunkSize of 3, it would return [[1,2,3],[2,3,4],[3,4,5],[4,5,6]]. A chunkSize of 2 would return [[1,2],[2,3],[3,4],[4,5],[5,6]].

Any thoughts on how to approach this?

有帮助吗?

解决方案

function chunk (array, chunkSize) {
    var retArr = [];
    for (var i = 0; i < array.length - (chunkSize - 1); i++) {
        retArr.push(array.slice(i, i + chunkSize));
    }
    return retArr;
}

If you did want to extend the prototype (probably would be better) it would looks like this:

Array.prototype.chunk = function( chunkSize ) {
    var retArr = [];
    for (var i = 0; i < this.length - (chunkSize - 1); i++) {
        retArr.push( this.slice(i, i + chunkSize));
    }
    return retArr;
}

其他提示

Using the more declarative and consise (IMO) aproach.

const data = [1,2,3,4,5,6];

function getGroups(dataList, groupSize) {
  return dataList
    .slice(groupSize - 1)
    .map((_, index) => dataList.slice(index, index + groupSize));
}
console.log("2:", JSON.stringify(getGroups(data, 2)));
console.log("3:", JSON.stringify(getGroups(data, 3)));

Firstly I remove the number of elements from the start of the array since number of elements in the output will be appropriately smaller. Then i loop over the remaining elements mapping them to appropriate groups.

I'm not really good with javaScript but this is algorithmically very easy to achieve with two nested for loops. Here is a solution in C# - you should be able to figure this out quite easily.

This used less than optimal data structures and everything but the algorithm itself is obvious.

protected List<List<int>> Split(List<int> array, int chunkSize)
{
    List<List<int>> result = new List<List<int>>();

    for (int i = 0; i < array.Count - chunkSize; i++)
    {
        List<int> temp = new List<int>();
        for (int j = i; j < i + chunkSize; j++)
        {
            temp.Add(array[j]);
        }
        result.Add(temp);
    }

    return result;
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top