Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/394.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 将数组拆分为块_Javascript_Arrays_Split - Fatal编程技术网

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) {

假设我有一个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) {
    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
?[…段,