Bil*_*ill 70 javascript arrays jquery loops
我有一系列的电子邮件(它可能只是一封电子邮件,或100封电子邮件),我需要发送带有ajax请求的数组(我知道该怎么做),但我只能发送一个包含10个或更少的电子邮件.因此,如果有一个包含20个电子邮件的原始数组,我需要将它们分成2个数组,每个10个.或者如果原始数组中有15个电子邮件,那么1个数组为10,另一个数组为5.我正在使用jQuery,最好的方法是什么?
jyo*_*ore 149
不要使用jquery ...使用普通的javascript
var a = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
var b = a.splice(0,10);
//a is now [11,12,13,14,15];
//b is now [1,2,3,4,5,6,7,8,9,10];
Run Code Online (Sandbox Code Playgroud)
你可以循环这个来获得你想要的行为.
var a = YOUR_ARRAY;
while(a.length) {
console.log(a.splice(0,10));
}
Run Code Online (Sandbox Code Playgroud)
这将一次给你10个元素...如果你说15个元素,你会得到1-10,你想要的11-15.
Bla*_*ger 83
var size = 10; var arrayOfArrays = [];
for (var i=0; i<bigarray.length; i+=size) {
arrayOfArrays.push(bigarray.slice(i,i+size));
}
console.log(arrayOfArrays);
Run Code Online (Sandbox Code Playgroud)
不同于splice(),slice()对原始数组是非破坏性的.
Cla*_*dio 28
只需循环遍历数组,拼接它直到它全部被消耗掉.
var a = ['a','b','c','d','e','f','g']
, chunk
while (a.length > 0) {
chunk = a.splice(0,3)
console.log(chunk)
}
Run Code Online (Sandbox Code Playgroud)
产量
[ 'a', 'b', 'c' ]
[ 'd', 'e', 'f' ]
[ 'g' ]
Run Code Online (Sandbox Code Playgroud)
Ale*_*nov 27
您可以使用lodash:https://lodash.com/docs
_.chunk(['a', 'b', 'c', 'd'], 2);
// ? [['a', 'b'], ['c', 'd']]
Run Code Online (Sandbox Code Playgroud)
小智 13
Array.reduce 对于大型数组可能效率低下,尤其是使用 mod 运算符。我认为一个更干净(并且可能更容易阅读)的功能解决方案是这样的:
const chunkArray = (arr, size) =>
arr.length > size
? [arr.slice(0, size), ...chunkArray(arr.slice(size), size)]
: [arr];
Run Code Online (Sandbox Code Playgroud)
jfr*_*d00 11
假设您不想销毁原始数组,可以使用这样的代码将长数组拆分为更小的数组,然后可以迭代:
var longArray = []; // assume this has 100 or more email addresses in it
var shortArrays = [], i, len;
for (i = 0, len = longArray.length; i < len; i += 10) {
shortArrays.push(longArray.slice(i, i + 10));
}
// now you can iterate over shortArrays which is an
// array of arrays where each array has 10 or fewer
// of the original email addresses in it
for (i = 0, len = shortArrays.length; i < len; i++) {
// shortArrays[i] is an array of email addresss of 10 or less
}
Run Code Online (Sandbox Code Playgroud)
另一个实现:
const arr = ["H", "o", "w", " ", "t", "o", " ", "s", "p", "l", "i", "t", " ", "a", " ", "l", "o", "n", "g", " ", "a", "r", "r", "a", "y", " ", "i", "n", "t", "o", " ", "s", "m", "a", "l", "l", "e", "r", " ", "a", "r", "r", "a", "y", "s", ",", " ", "w", "i", "t", "h", " ", "J", "a", "v", "a", "S", "c", "r", "i", "p", "t"];
const size = 3;
const res = arr.reduce((acc, curr, i) => {
if ( !(i % size) ) { // if index is 0 or can be divided by the `size`...
acc.push(arr.slice(i, i + size)); // ..push a chunk of the original array to the accumulator
}
return acc;
}, []);
// => [["H", "o", "w"], [" ", "t", "o"], [" ", "s", "p"], ["l", "i", "t"], [" ", "a", " "], ["l", "o", "n"], ["g", " ", "a"], ["r", "r", "a"], ["y", " ", "i"], ["n", "t", "o"], [" ", "s", "m"], ["a", "l", "l"], ["e", "r", " "], ["a", "r", "r"], ["a", "y", "s"], [",", " ", "w"], ["i", "t", "h"], [" ", "J", "a"], ["v", "a", "S"], ["c", "r", "i"], ["p", "t"]]
Run Code Online (Sandbox Code Playgroud)
注意 - 这不会修改原始数组。
或者,如果您更喜欢函数式的、100% 不可变的(尽管像上面所做的那样就地变异确实没有什么不好)和自包含方法:
function splitBy(size, list) {
return list.reduce((acc, curr, i, self) => {
if ( !(i % size) ) {
return [
...acc,
self.slice(i, i + size),
];
}
return acc;
}, []);
}
Run Code Online (Sandbox Code Playgroud)
作为@jyore 答案的补充,如果您仍想保留原始数组:
var originalArray = [1,2,3,4,5,6,7,8];
var splitArray = function (arr, size) {
var arr2 = arr.slice(0),
arrays = [];
while (arr2.length > 0) {
arrays.push(arr2.splice(0, size));
}
return arrays;
}
splitArray(originalArray, 2);
// originalArray is still = [1,2,3,4,5,6,7,8];
Run Code Online (Sandbox Code Playgroud)
尽管姗姗来迟,但ES6 生成器开辟了另一种巧妙的方式来实现所要求的目标。
/**
* Returns chunks of size n.
* @param {Array<any>} array any array
* @param {number} n size of chunk
*/
function* chunks(array, n){
for(let i = 0; i < array.length; i += n) yield array.slice(i, i + n);
}
const result = [...chunks([1, 2, 3, 4, 5, 6, 7, 8 , 9, 10], 3)];
console.log(result);Run Code Online (Sandbox Code Playgroud)
.as-console-wrapper { max-height: 100% !important; top: 0; }Run Code Online (Sandbox Code Playgroud)
使用相同的想法,您可以创建一个生成器,它还可以根据n-sized从另一个(可能是无限的)生成器函数检索的值生成无限数量的块。一旦需要,这对于延迟生成值来说非常方便,这会显着减少所需的内存,甚至可以用于生成可能无限/未知数量的块。
这是一个使用两个生成器的示例。
nextNaturalNumber()是一个无限生成器,它总是返回下一个自然数。我bigint在这里使用 ES2020 数据类型,因此值的大小没有限制(通过 JavaScript)。chunksFromIterable()从可能无限的可迭代对象中创建n-sized块。/**
* Returns chunks of size n for a possibly infinite iterator.
* n must be >= 1
* @param {Iterable<any>} iterable any array
* @param {number} n size of chunk for n >= 1
*/
function* chunksFromIterable(iterable, n){
let arr = [];
let i = n;
for (const value of iterable) {
if(i <= 0) {
// another chunk of size n is filled => return chunk
yield arr;
arr = []; // create new empty array
i = n;
};
arr.push(value);
i--;
}
// in case the iterable is not infinite check if there are still values in the array and return them if necessary
if(arr.length > 0) yield arr;
}
/**
* Infinite iterator which always gets the next natural number.
*/
function* nextNaturalNumber(){
let i = 0n;
while(true) {
i += 1n;
yield i;
}
}
console.log("Finite iterable:");
// this version can now be used using the for ... of loop
for(const threeNaturalNumbers of chunksFromIterable([1, 2, 3, 4, 5, 6, 7, 8 , 9, 10], 3)){
console.log(threeNaturalNumbers);
}
console.log("Infinite iterable:");
// and it can also be used for this infinite generator
for(const threeNaturalNumbers of chunksFromIterable(nextNaturalNumber(), 3)){
printBigIntArray(threeNaturalNumbers);
if(threeNaturalNumbers[0] > 30) break; // end here to avoid an infinite loop
}
// helper function to print array of bigints as this does not seem to be working for snippets
function printBigIntArray(arr){
console.log(`[${arr.join(", ")}]`);
}Run Code Online (Sandbox Code Playgroud)
.as-console-wrapper { max-height: 100% !important; top: 0; }Run Code Online (Sandbox Code Playgroud)