让我们说我有一个Javascript数组看起来如下:
["Element 1","Element 2","Element 3",...]; // with close to a hundred elements.
什么样的方法适合将数组分成许多更小的数组,假设最多有10个元素?
让我们说我有一个Javascript数组看起来如下:
["Element 1","Element 2","Element 3",...]; // with close to a hundred elements.
什么样的方法适合将数组分成许多更小的数组,假设最多有10个元素?
当前回答
ES6传播功能#ohmy #ftw
Const chunk = (size, xs) => xs.reduce ( (segments, _, index) => 索引%大小=== 0 ? […段,x。Slice (index, index + size)] 段, [] ); console.log(块(3,(1,2,3,4,5,6,7,8)));
其他回答
这是一个带有尾递归和数组解构的版本。
远非最快的性能,但我只是觉得好笑,js现在可以做到这一点。即使它没有为此进行优化:(
const getChunks = (arr, chunk_size, acc = []) => {
if (arr.length === 0) { return acc }
const [hd, tl] = [ arr.slice(0, chunk_size), arr.slice(chunk_size) ]
return getChunks(tl, chunk_size, acc.concat([hd]))
}
// USAGE
const my_arr = [1,2,3,4,5,6,7,8,9]
const chunks = getChunks(my_arr, 2)
console.log(chunks) // [[1,2],[3,4], [5,6], [7,8], [9]]
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将导致无限循环。
我创建了以下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个元素)。
这段代码适用于每一个场景,您甚至可以更改分隔符以匹配您想要获得的任何数组大小。很甜蜜吧:-)
有什么问题吗?请在下方评论中提问。
这里是一个仅使用递归和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/
打印稿版本。演示了将101个随机uid分成10个组
const idArrayLengthLimit = 10;
const randomOneHundredOneIdArray = Array
.from(Array(101).keys())
.map(() => generateUid(5));
function generateUid(length: number) {
const uidString: string[] = [];
const uidChars = 'abcdefghijklmnopqrstuvwxyz0123456789';
for (let i = 0; i < length; i++) {
uidString
.push(uidChars.charAt(Math.floor(Math.random() * uidChars.length)));
}
return uidString.join('');
}
for (let i = 0; i < randomOneHundredOneIdArray.length; i++) {
if(i % idArrayLengthLimit === 0){
const result = randomOneHundredOneIdArray
.filter((_,id) => id >= i && id < i + idArrayLengthLimit);
// Observe result
console.log(result);
}
}