请考虑一个数组,例如:
arrayAll = [1,2,3,4,5,6,7,8,9]
是否有一个包可以进行分区以获得:
arrayALLPartionned = [[1,2,3],[4,5,6],[7,8,9]]
我可以看到如何使用 for 循环执行此操作,但如果存在“预制”函数,我将不胜感激。
请考虑一个数组,例如:
arrayAll = [1,2,3,4,5,6,7,8,9]
是否有一个包可以进行分区以获得:
arrayALLPartionned = [[1,2,3],[4,5,6],[7,8,9]]
我可以看到如何使用 for 循环执行此操作,但如果存在“预制”函数,我将不胜感激。
我认为你将不得不使用 for 循环,不知道任何内置函数......
试试这个功能:
function splitarray(input, spacing)
{
var output = [];
for (var i = 0; i < input.length; i += spacing)
{
output[output.length] = input.slice(i, i + spacing);
}
return output;
}
这是一个递归解决方案:
function partition(array, n) {
return array.length ? [array.splice(0, n)].concat(partition(array, n)) : [];
}
这利用了Array#splice
破坏性删除指定项目的事实,并将它们作为函数值返回。请注意,这将破坏输入数组,使其为空。
如果使用Underscore.js,您可以使用groupBy()
和values()
function partition(items, size) {
var result = _.groupBy(items, function(item, i) {
return Math.floor(i/size);
});
return _.values(result);
}
(这在 CoffeeScript 中没那么难看。)
jsFiddle:http : //jsfiddle.net/MW3BS/
另一种解决方案,没有外部库:
function partition(items, size) {
var p = [];
for (var i=Math.floor(items.length/size); i-->0; ) {
p[i]=items.slice(i*size, (i+1)*size);
}
return p;
}
我已将此解决方案添加到@dystroy 的 jspref 中,它的运行速度似乎是其他解决方案的两倍。编辑:在 Safari 和 Chrome 但不是 Firefox
这是功能风格的解决方案,可添加到此处的答案组合中。
它是一个被调用的高阶函数toPartitions
,它返回下划线的 reduce 方法或本机数组 reduce 方法的回调。
用法示例:
[1,2,3,4,5,6,7,8,9].reduce( toPartitions( 3 ), [] );
功能:
function toPartitions ( size ) {
var partition = [];
return function ( acc, v ) {
partition.push( v );
if ( partition.length === size ) {
acc.push( partition );
partition = [];
}
return acc;
};
}
与 Clojure 的分区一样,当元素不足时,它不会包含尾分区。
在您的示例中,您可以执行以下操作:
arrayALLPartionned = arrayAll.reduce( toPartitions( 3 ), [] ) );
如果您不想将其与 一起使用reduce
,而只想使用一个接受数组和分区大小的函数,您可以执行以下操作:
function partition ( arr, size ) {
return arr.reduce( toPartitions( size ), [] );
}
因此,解决方案将是:
arrayALLPartionned = partition( arrayAll, 3 );