让我们说我有一个Javascript数组看起来如下:

["Element 1","Element 2","Element 3",...]; // with close to a hundred elements.

什么样的方法适合将数组分成许多更小的数组,假设最多有10个元素?


当前回答

我最喜欢的是生成器generateChunks和附加函数getChunks来执行生成器。

function* generateChunks(array, size) {
    let start = 0;
    while (start < array.length) {
        yield array.slice(start, start + size);
        start += size;
    }
}

function getChunks(array, size) {
    return [...generateChunks(array, size)];
}

console.log(getChunks([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 3)) // [ [ 0, 1, 2 ], [ 3, 4, 5 ], [ 6, 7, 8 ], [ 9 ] ]

作为这里的补充,生成器使用进一步的getPartitions函数生成分区,以获得n个相同大小的数组。

function generatePartitions(array, count) {
    return generateChunks(array, Math.ceil(array.length / count));
}

function getPartitions(array, count) {
    return [...generatePartitions(array, count)];
}

console.log(getPartitions([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 3)) // [ [ 0, 1, 2, 3 ], [ 4, 5, 6, 7 ], [ 8, 9 ] ]

与许多其他解决方案相比,生成器的一个优点是不会创建多个不必要的数组。

其他回答

results = []
chunk_size = 10
while(array.length > 0){
   results.push(array.splice(0, chunk_size))
}

这里是一个仅使用递归和slice()的非突变解决方案。

const splitToChunks = (arr, chunkSize, acc = []) => (
    arr.length > chunkSize ?
        splitToChunks(
            arr.slice(chunkSize),
            chunkSize,
            [...acc, arr.slice(0, chunkSize)]
        ) :
        [...acc, arr]
);

然后简单地像splitToChunks([1,2,3,4,5], 3)一样使用它来获得[[1,2,3],[4,5]]。

这里有一个小提琴供你尝试:https://jsfiddle.net/6wtrbx6k/2/

我创建了以下JSFiddle来演示我解决您的问题的方法。

(function() { // Sample arrays var //elements = ["0", "1", "2", "3", "4", "5", "6", "7"], elements = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43"]; var splitElements = [], delimiter = 10; // Change this value as needed // parameters: array, number of elements to split the array by if(elements.length > delimiter){ splitElements = splitArray(elements, delimiter); } else { // No need to do anything if the array's length is less than the delimiter splitElements = elements; } //Displaying result in console for(element in splitElements){ if(splitElements.hasOwnProperty(element)){ console.log(element + " | " + splitElements[element]); } } })(); function splitArray(elements, delimiter) { var elements_length = elements.length; if (elements_length > delimiter) { var myArrays = [], // parent array, used to store each sub array first = 0, // used to capture the first element in each sub array index = 0; // used to set the index of each sub array for (var i = 0; i < elements_length; ++i) { if (i % delimiter === 0) { // Capture the first element of each sub array from the original array, when i is a modulus factor of the delimiter. first = i; } else if (delimiter - (i % delimiter) === 1) { // Build each sub array, from the original array, sliced every time the i one minus the modulus factor of the delimiter. index = (i + 1) / delimiter - 1; myArrays[index] = elements.slice(first, i + 1); } else if(i + 1 === elements_length){ // Build the last sub array which contain delimiter number or less elements myArrays[index + 1] = elements.slice(first, i + 1); } } // Returned is an array of arrays return myArrays; } }

首先,我有两个例子:一个数组少于8个元素,另一个数组多于8个元素(注释你不想使用的哪个数组)。

然后检查数组的大小,这很简单,但对于避免额外的计算是必要的。从这里开始,如果数组满足条件(数组大小为>分隔符),我们将移动到splitArray函数。

splitArray函数接受分隔符(即8,因为这是分隔符)和数组本身。由于我们经常重用数组长度,所以我将它缓存在一个变量中,以及第一个和最后一个变量中。

First表示数组中第一个元素的位置。这个数组是由8个元素组成的数组。为了确定第一个元素,我们使用模算子。

myArrays是数组的数组。其中,我们将在每个索引处存储大小为8或更小的子数组。这是下面算法中的关键策略。

index表示myArrays变量的索引。每次存储8个或更少元素的子数组时,都需要将其存储在相应的索引中。如果我们有27个元素,那就意味着4个数组。第一个、第二个和第三个数组各有8个元素。最后一个只包含3个元素。所以index分别是0 1 2和3。

棘手的部分仅仅是计算出数学并尽可能优化它。例如,else if (delimiter - (i % delimiter) === 1)这是为了找到数组中应该包含的最后一个元素,当数组将被满时(例如:包含10个元素)。

这段代码适用于每一个场景,您甚至可以更改分隔符以匹配您想要获得的任何数组大小。很甜蜜吧:-)

有什么问题吗?请在下方评论中提问。

我认为这是ES6语法的一个很好的递归解决方案:

Const chunk =函数(数组,大小){ If (!array.length) { 返回[]; } Const head = array。片(0,大小); Const tail = array.slice(size); 返回[头,…块(尾巴,大小)]; }; 块console.log(((1、2、3),2));

我的目标是在纯ES6中创建一个简单的非突变解决方案。javascript的特性使得在映射之前必须填充空数组:-(

function chunk(a, l) { 
    return new Array(Math.ceil(a.length / l)).fill(0)
        .map((_, n) => a.slice(n*l, n*l + l)); 
}

这个带有递归的版本似乎更简单,也更引人注目:

function chunk(a, l) { 
    if (a.length == 0) return []; 
    else return [a.slice(0, l)].concat(chunk(a.slice(l), l)); 
}

ES6中荒谬的弱数组函数可以制作出很好的谜题:-)