1

假设我们有一个可变长度的数组,我想通过最大长度为 100 的块来处理它,并以最小数量的块来处理它。因此,对于长度为 241 的数组,它将是 3 个大小为 41、100、100(或 100、100、41)的子数组。

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 循环之前的特殊情况。有任何想法吗?

4

5 回答 5

2

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

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);
于 2012-07-26T15:49:33.737 回答
1

使用分块功能~

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));
于 2012-07-26T15:50:49.243 回答
1

它是函数式递归解决方案。没有 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));​
于 2012-07-30T14:04:25.567 回答
0

不是真的,使用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;
    }, []);
}
于 2012-07-26T15:49:22.957 回答
0

让您的doSomethingWithSubArray函数接受起始索引并返回下一个未处理null的索引,或者如果没有更多工作。把这个“迭代器”放在一个while循环中。在条件中调用此“迭代器”之后,立即在块之间执行其余工作(更新 UI?)while

于 2012-07-26T15:51:05.210 回答