按子数组处理数组

Processing an array by sub arrays

本文关键字:数组 处理      更新时间:2024-02-26

假设我们有一个可变长度的数组,我想用最大长度为100的块来处理它,并用最小数量的块来进行处理。因此,对于长度为241的阵列,它将是大小为4100100(或10010041)的3个子阵列。

curr_len = arr.length;
offset = curr_len%100;
doSomethingWithSubArray(arr.slice(offset))
for(j = offset; j <= curr_len; j = j+100){
    doSomethingWithSubArray(arr.slice(j,j+100))
}

我相信有更优雅的方法可以做到这一点,可能在for循环之前没有特殊情况。有什么想法吗?

我希望最后一个块的大小更小。那么代码将是:

for (var i=0; i<arr.length; i+=100)
    doSomethingWithSubArray(arr.slice(i, 100));

这正是我的splitBy函数所做的:

Array.prototype.splitBy = function(n) {
/* get: number of items per array
return: array of n-sized arrays with the items (last array may contain less then n) */
    for (var r=[], i=0; i<this.length; i+=n)
        r.push(this.slice(i, i+n));
    return r;
}

然后只写:

arr.splitBy(100).forEach(doSomethingWithSubArray);

使用区块函数~

function chunk(a, s){
    for(var x, i = 0, c = -1, l = a.length, n = []; i < l; i++)
        (x = i % s) ? n[c][x] = a[i] : n[++c] = [a[i]];
    return n;
}
console.log(chunk([1,2,3,4,5,6,7,8,9,10], 3));

它是函数式递归解决方案。没有var,没有循环,没有计数,因为它更清晰

var chunk = function(arr, n){
    if (arr.length == 0) return [];
    var head = arr.slice(0, n), rest = arr.slice(n);
    return [head].concat( chunk(rest, n) );
};
console.log(chunk([1,2,3,4,5,6,7,8,9,10], 3));​

不是这样,使用reduce看起来像这样:

var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
var splitArrays = array.reduce(function(arr, cur, i) {
    if (i % 3 === 0) arr.push([]);
    arr[i / 3 | 0].push(cur);
    return arr;
}, []);
//splitArrays looks like:
//[[1,2,3],[4,5,6],[7,8,9],[10,11]]

更通用的功能

function splitArray(array, num) {
    return array.reduce(function(arr, cur, i) {
        if (i % num === 0) arr.push([]);
        arr[i / num | 0].push(cur);
        return arr;
    }, []);
}

使doSomethingWithSubArray函数接受一个起始索引,并在没有更多工作的情况下返回下一个未处理的索引或null。将这个"迭代器"放入while循环中。在while条件中调用这个"迭代器"之后,立即在块之间完成您想做的其余工作(更新UI?)。