Particionar em JavaScript

Por favor, considere uma matriz como:

arrayAll = [1,2,3,4,5,6,7,8,9] 

Existe um pacote que permite fazer o particionamento para obter:

 arrayALLPartionned = [[1,2,3],[4,5,6],[7,8,9]] 

Eu posso ver como fazer isso com um loop for, mas gostaria de uma function “pré-fabricada”, se existente.

Se estiver usando Underscore.js , você pode implementar isso com groupBy() e values()

 function partition(items, size) { var result = _.groupBy(items, function(item, i) { return Math.floor(i/size); }); return _.values(result); } 

(Isso é menos feio no CoffeeScript .)

jsFiddle: http://jsfiddle.net/MW3BS/

Eu acho que você terá que usar um loop for, não sei de nenhuma function embutida …

Experimente esta function:

 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; } 

Aqui está uma solução recursiva:

 function partition(array, n) { return array.length ? [array.splice(0, n)].concat(partition(array, n)) : []; } 

Isso aproveita o fato de que Array#splice remove os itens especificados de forma destrutiva e os retorna como o valor da function. Observe que isso destruirá a matriz de input, deixando-a vazia.

Mais uma solução, sem biblioteca externa:

 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; } 

Demonstração: http://jsfiddle.net/dystroy/xtHXZ/

Eu adicionei esta solução ao jspref do @dystroy aqui e parece rodar duas vezes mais rápido que as outras soluções. Editar: no Safari e no Chrome, mas não no Firefox

Aqui está uma solução de estilo funcional para adicionar à mistura de respostas aqui.

É uma function de ordem superior chamada toPartitions que retorna um retorno de chamada para o método de redução de sublinhado ou o método de redução de matriz nativa.

Exemplo de uso:

 [1,2,3,4,5,6,7,8,9].reduce( toPartitions( 3 ), [] ); 

A function:

 function toPartitions ( size ) { var partition = []; return function ( acc, v ) { partition.push( v ); if ( partition.length === size ) { acc.push( partition ); partition = []; } return acc; }; } 

Como a partição do Clojure, ela não includeá uma partição final quando não houver elementos suficientes.

No seu exemplo, você poderia fazer:

 arrayALLPartionned = arrayAll.reduce( toPartitions( 3 ), [] ) ); 

Se você não quiser usar isso com reduce , mas apenas tenha uma function que tenha um tamanho de matriz e partição que você poderia fazer:

 function partition ( arr, size ) { return arr.reduce( toPartitions( size ), [] ); } 

Portanto, a solução seria apenas:

 arrayALLPartionned = partition( arrayAll, 3 ); 

Prototype tem uma function array.partition, bem como uma function eachSlice (). Soa como eachSlice () é o que você está procurando. Se você estiver usando jquery, há um plug-in para poder usar funções de protótipo. Aqui está um link para ele … http://www.learningjquery.com/2009/02/implementing-prototypes-array-methods-in-jquery

Você pode escrever seu próprio método de protótipo para fazer isso

 Array.prototype.partition = function(length) { var result = []; for(var i = 0; i < this.length; i++) { if(i % length === 0) result.push([]); result[result.length - 1].push(this[i]); } return result; }; 

Se preferir não adicionar ao protótipo nativo, você pode escrever uma function simples:

 var partition = function(arr, length) { var result = []; for(var i = 0; i < arr.length; i++) { if(i % length === 0) result.push([]); result[result.length - 1].push(arr[i]); } return result; }; 

Você pode vê-lo em ação nesta demonstração do jsFiddle .