Javascript 将数组拆分为块
假设我有一个Javascript数组,如下所示:Javascript 将数组拆分为块,javascript,arrays,split,Javascript,Arrays,Split,假设我有一个Javascript数组,如下所示: ["Element 1","Element 2","Element 3",...]; // with close to a hundred elements. 什么方法适合将数组分块(拆分)为多个较小的数组,最多10个元素?该方法可以从数组的开头、中间或结尾提取一个切片,而无需更改原始数组 var i,j,temparray,chunk = 10; for (i=0,j=array.length; i<j; i+=chunk) {
["Element 1","Element 2","Element 3",...]; // with close to a hundred elements.
什么方法适合将数组分块(拆分)为多个较小的数组,最多10个元素?该方法可以从数组的开头、中间或结尾提取一个切片,而无需更改原始数组
var i,j,temparray,chunk = 10;
for (i=0,j=array.length; i<j; i+=chunk) {
temparray = array.slice(i,i+chunk);
// do whatever
}
var i,j,temparray,chunk=10;
对于(i=0,j=array.length;i由dbaseman的答案修改而成):
Object.defineProperty(Array.prototype,'chunk\u'{
值:函数(chunkSize){
var数组=这个;
返回[]。concat.apply([],
array.map(函数(elem,i){
返回i%chunkSize?[]:[array.slice(i,i+chunkSize)];
})
);
}
});
console.log(
[1,2,3,4,5,6,7].块(3)
)
//[[1,2,3],[4,5,6],[7]
旧问题:新答案!我实际上是在研究这个问题的答案,并让一位朋友对其进行了改进!因此,它是:
Array.prototype.chunk = function ( n ) {
if ( !this.length ) {
return [];
}
return [ this.slice( 0, n ) ].concat( this.slice(n).chunk(n) );
};
[1,2,3,4,5,6,7,8,9,0].chunk(3);
> [[1,2,3],[4,5,6],[7,8,9],[0]]
如果您不知道谁将使用您的代码(第三方、同事、您自己等),请尽量避免使用本机原型,包括Array.prototype
有一些方法可以安全地扩展原型(但不是在所有浏览器中),也有一些方法可以安全地使用从扩展原型创建的对象,但更好的经验法则是遵循规则并完全避免这些做法
如果您有时间,请观看Andrew Dupont的JSConf 2011演讲,了解有关此主题的详细讨论
但回到问题上来,尽管上述解决方案可行,但它们过于复杂,需要不必要的计算开销。以下是我的解决方案:
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;
功能块(arr,len){
var chunks=[],
i=0,
n=阵列长度;
而(i
我更喜欢使用以下方法:
好的,让我们从一个相当紧凑的开始:
function chunk(arr, n) {
return arr.slice(0,(arr.length+n-1)/n|0).
map(function(c,i) { return arr.slice(n*i,n*i+n); });
}
它是这样使用的:
chunk([1,2,3,4,5,6,7], 2);
[1,2,3,4,5,6,7].reduce(chunker.bind(3),[]);
[1,2,3,4,5,6,7].reduce(chunker(3),[]);
// 0: [[1, 2, 3]]
// 1: [[1, 2, 3]]
// 2: [[1, 2, 3]]
// 3: [[1, 2, 3], [4, 5, 6]]
// 4: [[1, 2, 3], [4, 5, 6]]
// 5: [[1, 2, 3], [4, 5, 6]]
// 6: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
// 7: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
// 8: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
// 9: [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
然后我们有了这个紧密减速器功能:
function chunker(p, c, i) {
(p[i/this|0] = p[i/this|0] || []).push(c);
return p;
}
它是这样使用的:
chunk([1,2,3,4,5,6,7], 2);
[1,2,3,4,5,6,7].reduce(chunker.bind(3),[]);
[1,2,3,4,5,6,7].reduce(chunker(3),[]);
// 0: [[1, 2, 3]]
// 1: [[1, 2, 3]]
// 2: [[1, 2, 3]]
// 3: [[1, 2, 3], [4, 5, 6]]
// 4: [[1, 2, 3], [4, 5, 6]]
// 5: [[1, 2, 3], [4, 5, 6]]
// 6: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
// 7: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
// 8: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
// 9: [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
因为当我们将这个
绑定到一个数字时,小猫就死了,所以我们可以这样做:
// Fluent alternative API without prototype hacks.
function chunker(n) {
return function(p, c, i) {
(p[i/n|0] = p[i/n|0] || []).push(c);
return p;
};
}
它是这样使用的:
chunk([1,2,3,4,5,6,7], 2);
[1,2,3,4,5,6,7].reduce(chunker.bind(3),[]);
[1,2,3,4,5,6,7].reduce(chunker(3),[]);
// 0: [[1, 2, 3]]
// 1: [[1, 2, 3]]
// 2: [[1, 2, 3]]
// 3: [[1, 2, 3], [4, 5, 6]]
// 4: [[1, 2, 3], [4, 5, 6]]
// 5: [[1, 2, 3], [4, 5, 6]]
// 6: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
// 7: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
// 8: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
// 9: [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
然后是仍然非常紧凑的函数,它一次完成所有功能:
function chunk(arr, n) {
return arr.reduce(function(p, cur, i) {
(p[i/n|0] = p[i/n|0] || []).push(cur);
return p;
},[]);
}
chunk([1,2,3,4,5,6,7], 3);
我在jsperf.com上测试了不同的答案。结果可在那里获得:
最快的功能(从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;
}
功能块(arr,chunkSize){
如果(chunkSize现在,您可以使用lodash的chunk函数将数组拆分为更小的数组,而无需再处理循环!为此创建了一个npm包
var结果=[];
对于(变量i=0;i
当使用
var结果=[];
对于(变量i=0;i
如果使用EcmaScript version>=5.1,则可以使用具有O(N)复杂性的
函数块(chunkSize,数组){
返回数组.reduce(函数(上一个,当前){
var组块;
如果(previous.length==0 | |
previous[previous.length-1]。长度===chunkSize){
chunk=[];//1
previous.push(块);//2
}
否则{
chunk=previous[previous.length-1];//3
}
chunk.push(当前);//4
返回上一个;//5
}, []); // 6
}
log(块(2,['a','b','c','d','e']);
//打印[['a','b',['c','d',['e']]
这是一个使用reduce的ES6版本
var perChunk=2//每个区块的项目数
变量inputArray=['a'、'b'、'c'、'd'、'e']
var result=inputArray.reduce((resultArray,item,index)=>{
常量chunkIndex=数学楼层(索引/高位)
如果(!resultArray[chunkIndex]){
resultArray[chunkIndex]=[]//启动一个新块
}
resultArray[chunkIndex]。推送(项)
返回结果数组
}, [])
console.log(result);//结果:['a','b',['c','d',['e']]
ES6版本
这将是我对这个主题的贡献。我想.reduce()
是最好的方法
var段=(arr,n)=>arr.reduce((r,e,i)=>i%n?(r[r.length-1]。推(e),r)
:(r.push([e]),r),[]),
arr=Array.from({length:31}).map(({,i)=>i+1);
res=段(arr,7);
console.log(JSON.stringify(res));
ECMA6中的一行程序
const [list,chunkSize] = [[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15], 6]
[...Array(Math.ceil(list.length / chunkSize))].map(_ => list.splice(0,chunkSize))
对于功能解决方案,使用:
其中,popularProducts
是您的输入数组,5
是块大小
import splitEvery from'ramda/src/splitEvery'
splitEvery(5,popularProducts).map((块,i)=>{
//用chunk做点什么
})
我的目标是在纯ES6中创建一个简单的非变异解决方案。javascript的特性使得在映射之前有必要填充空数组:-(
这个带有递归的版本似乎更简单、更引人注目:
function chunk(a, l) {
if (a.length == 0) return [];
else return [a.slice(0, l)].concat(chunk(a.slice(l), l));
}
ES6的数组函数弱得可笑,这是一个很好的谜题:-)有很多答案,但这就是我使用的:
const chunk = (arr, size) =>
arr
.reduce((acc, _, i) =>
(i % size)
? acc
: [...acc, arr.slice(i, i + size)]
, [])
// USAGE
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
chunk(numbers, 3)
// [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
首先,在将索引除以块大小时检查余数
如果有余数,则返回累加器数组
如果没有余数,则索引可以被块大小整除,因此从原始数组中获取一个切片(从当前索引开始),并将其添加到累加器数组中
因此,reduce每次迭代返回的累加器数组如下所示:
chunk([1,2,3,4,5,6,7], 2);
[1,2,3,4,5,6,7].reduce(chunker.bind(3),[]);
[1,2,3,4,5,6,7].reduce(chunker(3),[]);
// 0: [[1, 2, 3]]
// 1: [[1, 2, 3]]
// 2: [[1, 2, 3]]
// 3: [[1, 2, 3], [4, 5, 6]]
// 4: [[1, 2, 3], [4, 5, 6]]
// 5: [[1, 2, 3], [4, 5, 6]]
// 6: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
// 7: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
// 8: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
// 9: [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
ES6扩展功能性#欧姆#ftw
const块=
(大小,xs)=>
减少(
(段、段、索引)=>
索引%size==0
?[…段,