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

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

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


当前回答

下面是使用reduce()方法的另一个解决方案,尽管与其他示例略有不同。希望我的解释也能更清楚一点。

Var arr = [0,1,2,3,4,5,6,7]; var chunkSize = 3; Arr = Arr。Reduce ((acc, item, idx) => { Let group = acc.pop(); 如果(集团。长度== chunkSize) { acc.push(集团); Group = []; } group.push(项); acc.push(集团); 返回acc; }, [[]]); console.log (arr);//打印[[0,1,2],[3,4,5],[6,7]]


解释

我们称之为reducer,它对数组中的每一项都使用pop()获取累加器的最后一项。记住,这个项是一个数组,它将最多为chunkSize数量的项进行分组(在本例中为3)。

当且仅当该组的数组长度等于chunksize时,我们需要将该组重新插入到累加器中并创建一个新组。

然后将当前项推入我们的组数组(它可能已经包含前面步骤中的0、1或2个项)。将当前项插入组后,我们需要将组重新插入到更大的集合中。

该过程将重复进行,直到遍历arr中的所有项。

注意,我们还使用[[]]为减速器提供了数组中空数组的起始值。

其他回答

一个有效的解决方案是通过indexChunk将解决方案与slice和push连接起来,解决方案被分割成块:

function splitChunks(sourceArray, chunkSize) { if(chunkSize <= 0) throw "chunkSize must be greater than 0"; let result = []; for (var i = 0; i < sourceArray.length; i += chunkSize) { result[i / chunkSize] = sourceArray.slice(i, i + chunkSize); } return result; } let ar1 = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 ]; console.log("Split in chunks with 4 size", splitChunks(ar1, 4)); console.log("Split in chunks with 7 size", splitChunks(ar1, 7));

尽量避免搞乱原生原型,包括Array。原型,如果你不知道谁将使用你的代码(第三方、同事、你自己等)。

有一些方法可以安全地扩展原型(但不是在所有浏览器中),也有一些方法可以安全地使用从扩展原型创建的对象,但更好的经验法则是遵循最小意外原则,并完全避免这些做法。

如果你有时间,可以看看Andrew Dupont的JSConf 2011演讲,“Everything is allowed: Extending Built-ins”,关于这个话题的讨论。

但回到问题上来,虽然上面的解决方案是可行的,但它们过于复杂,需要不必要的计算开销。以下是我的解决方案:

function chunk (arr, len) {

  var chunks = [],
      i = 0,
      n = arr.length;

  while (i < n) {
    chunks.push(arr.slice(i, i += len));
  }

  return chunks;
}

// Optionally, you can do the following to avoid cluttering the global namespace:
Array.chunk = chunk;

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

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

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

array.slice()方法可以根据需要从数组的开头、中间或结尾提取切片,而不需要改变原始数组。

const chunkSize = 10;
for (let i = 0; i < array.length; i += chunkSize) {
    const chunk = array.slice(i, i + chunkSize);
    // do whatever
}

最后一个块可能小于chunkSize。例如,当给定一个包含12个元素的数组时,第一个块将有10个元素,第二个块只有2个。

注意,chunkSize为0将导致无限循环。

这里是一个仅使用递归和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/