如何使用JavaScript将长数组分割成更小的数组
我有一个电子邮件(它可以只是一个电子邮件,或100封电子邮件),我需要发送一个ajax请求(我知道该怎么做),但我只能发送一个数组10个或更less的电子邮件。 所以如果有20个电子邮件的原始数组,我需要将它们分成两个10个数组。 或者如果在原始数组中有15个电子邮件,那么1个数组是10,另一个数组是5.我正在使用jQuery,最好的方法是什么?
不要使用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];
你可以循环这个来获得你想要的行为。
var a = YOUR_ARRAY; while(a.length) { console.log(a.splice(0,10)); }
这会给你10个元素,如果你有15个元素,你会得到1-10,11-15,如你所想。
var size = 10; for (var i=0; i<bigarray.length; i+=size) { var smallarray = bigarray.slice(i,i+size); // do something with smallarray }
与splice()
不同, slice()
对原始数组没有破坏性。
只需循环遍历数组,拼接它直到全部消耗完。
var a = ['a','b','c','d','e','f','g'] , chunk while (a.length > 0) { chunk = a.splice(0,3) console.log(chunk) }
产量
[ 'a', 'b', 'c' ] [ 'd', 'e', 'f' ] [ 'g' ]
你可以使用lodash: https ://lodash.com/docs
_.chunk(['a', 'b', 'c', 'd'], 2); // → [['a', 'b'], ['c', 'd']]
假设你不想破坏原始数组,你可以使用这样的代码将长arrays分解成更小的数组,然后迭代:
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 }
作为@ 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];
另一个实现:
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"]]
NB – 这不会修改原始数组。
或者,如果您更喜欢function性的,不变的,独立的方法:
function splitBy(size, list) { return list.reduce((acc, curr, i, self) => { if ( !(i % size) ) { return [ ...acc, self.slice(i, i + size), ]; } return acc; }, []); }
你可以看看这个代码。 简单而有效。
function chunkArrayInGroups(array, unit) { var results = [], length = Math.ceil(array.length / unit); for (var i = 0; i < length; i++) { results.push(array.slice(i * unit, (i + 1) * unit)); } return results; } chunkArrayInGroups(["a", "b", "c", "d"], 2);
另一种方法:
var longArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; var size = 2; var newArray = new Array(Math.ceil(longArray.length / size)).fill("") .map(function() { return this.splice(0, size) }, longArray.slice()); // newArray = [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]];
这不会影响原始数组,因为使用slice创build的副本会传递到map的“this”参数中。
这是一个简单的单线程
var segment = (arr, n) => arr.reduce((r,e,i) => i%n ? (r[r.length-1].push(e), r) : (r.push([e]), r), []), arr = Array.from({length: 31}).map((_,i) => i+1); console.log(segment(arr,7));
我也想分享我的解决scheme。 这有点冗长,但也适用。
var data = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]; var chunksize = 4; var chunks = []; data.forEach((item)=>{ if(!chunks.length || chunks[chunks.length-1].length == chunksize) chunks.push([]); chunks[chunks.length-1].push(item); }); console.log(chunks);
输出(格式):
[ [ 1, 2, 3, 4], [ 5, 6, 7, 8], [ 9, 10, 11, 12], [13, 14, 15 ] ]
如果你想要一个不修改现有数组的方法,试试这个:
let oldArray = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]; let newArray = []; let size = 3; // Size of chunks you are after let j = 0; // This helps us keep track of the child arrays for (var i = 0; i < oldArray.length; i++) { if (i % size === 0) { j++ } if(!newArray[j]) newArray[j] = []; newArray[j].push(oldArray[i]) }
另一个实现,使用Array.reduce(我认为这是唯一缺less的!):
const splitArray = (arr, size) => { if (size === 0) { return []; } return arr.reduce((split, element, index) => { index % size === 0 ? split.push([element]) : split[Math.floor(index / size)].push(element); return split; }, []); };
上面有很多解决scheme,这个是非破坏性的。 当大小为0时返回一个空数组只是一个约定。 如果if
块被省略,你会得到一个错误,这可能是你想要的。