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

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

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


当前回答

对于功能性的解决方案,使用Ramda:

其中,popularProducts是输入数组,5是数据块大小

导入splitEvery from 'ramda/src/splitEvery' popularProducts splitEvery(5)。Map ((chunk, i) => { //用chunk做一些事情 })

其他回答

编辑:@mblase75在我写我的答案时在前面的答案上添加了更简洁的代码,所以我建议使用他的解决方案。

你可以使用这样的代码:

var longArray = ["Element 1","Element 2","Element 3", /*...*/];
var smallerArrays = []; // will contain the sub-arrays of 10 elements each
var arraySize = 10;
for (var i=0;i<Math.ceil(longArray.length/arraySize);i++) {
    smallerArrays.push(longArray.slice(i*arraySize,i*arraySize+arraySize));
}

修改arraySize的值可以改变较小数组的最大长度。

我在jsperf.com上测试了不同的答案。结果可以在https://web.archive.org/web/20150909134228/https://jsperf.com/chunk-mtds上找到

最快的函数(从IE8开始运行)是这个:

function chunk(arr, chunkSize) {
  if (chunkSize <= 0) throw "Invalid chunk size";
  var R = [];
  for (var i=0,len=arr.length; i<len; i+=chunkSize)
    R.push(arr.slice(i,i+chunkSize));
  return R;
}

我创建了以下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个元素)。

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

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

这是我能想到的最有效、最直接的解决方案:

function chunk(array, chunkSize) {
    let chunkCount = Math.ceil(array.length / chunkSize);
    let chunks = new Array(chunkCount);
    for(let i = 0, j = 0, k = chunkSize; i < chunkCount; ++i) {
        chunks[i] = array.slice(j, k);
        j = k;
        k += chunkSize;
    }
    return chunks;
}

下面是一个使用ImmutableJS的解决方案,其中items是一个不可变列表,size是所需的分组大小。

const partition = ((items, size) => {
  return items.groupBy((items, i) => Math.floor(i/size))
})