783 votes

Tableau de Split en morceaux

Disons que j’ai un tableau Javascript à la recherche comme suit :

Quelle approche serait approprié de morceau (split) du tableau en nombreux petits tableaux avec, disons, 10 éléments au plus ?

924voto

Blazemonger Points 39230

La nouvelle méthode array.slice peut extraire une tranche depuis le début, milieu ou fin d’un tableau buts vous avez besoin.

170voto

ninjagecko Points 25709

Modifié à partir d'une réponse par dbaseman: http://stackoverflow.com/a/10456344/711085

Array.prototype.chunk = function(chunkSize) {
    var array=this;
    return [].concat.apply([],
        array.map(function(elem,i) {
            return i%chunkSize ? [] : [array.slice(i,i+chunkSize)];
        })
    );
}

Démo:

> [1,2,3,4,5,6,7].chunk(3)
[[1,2,3],[4,5,6],[7]]

mineur addendum:

Je tiens à souligner que le dessus est un pas-que-élégant (dans mon esprit) programmation fonctionnelle solution de contournement. Il fait de la suivante, où ~ est la concaténation:

[[1,2,3]]~[]~[]~[] ~ [[4,5,6]]~[]~[]~[] ~ [[7]]

Il a le même temps d'exécution asymptotique que la méthode ci-dessous, mais peut-être un pire facteur constant en raison de bâtiment vide listes. On peut réécrire comme suit (pour la plupart les mêmes que Blazemonger de la méthode, c'est pourquoi je n'ai pas à l'origine de soumettre cette réponse):

Array.prototype.chunk = function(chunkSize) {
    var R = [];
    for (var i=0; i<this.length; i+=chunkSize)
        R.push(this.slice(i,i+chunkSize));
    return R;
}

[l'édition de cette réponse parce que cette question a mal été marquée d'un double]

alternativement, vous pouvez faire:

Array.range = function(n) {
  // Array.range(5) --> [0,1,2,3,4]
  return Array.apply(null,Array(n)).map(function(x,i){return i})
};

Object.defineProperty(Array.prototype, 'chunk', {
  value: function(n) {

    // ACTUAL CODE FOR CHUNKING ARRAY:
    return Array.range(Math.ceil(this.length/n)).map(function(x,i){
      return this.slice(i*n,i*n+n);
    }.bind(this));

  }
});

Démo:

> JSON.stringify( Array.range(10).chunk(3) );
[[1,2,3],[4,5,6],[7,8,9],[10]]

137voto

furf Points 769

Essayez d'éviter de coucher avec des prototypes natifs, y compris le Tableau.prototype, si vous ne savez pas qui va le consommer votre code (3e parties, des collègues de travail, - vous à une date ultérieure, etc.).

Il y a des moyens de sécurité étendre prototypes (mais pas dans tous les navigateurs) et il y a des façons de consommer sans danger des objets créés à partir étendue des prototypes, mais une meilleure règle de base est de suivre le Principe de moindre Surprise et d'éviter ces pratiques tout à fait.

Si vous avez un peu de temps, regardez André Dupont de JSConf 2011 parler, "Tout est Permis: l'Extension de Built-ins", pour une bonne discussion sur ce sujet.

Mais pour en revenir à la question, alors que les solutions ci-dessus ne fonctionne, ils sont trop complexes et nécessitant inutile de calcul des frais généraux. Voici ma solution:

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;

43voto

Arek Flinik Points 101

Je préfère utiliser la méthode splice :

35voto

rlemon Points 10016

Vieille question : nouvelle réponse ! En fait, je travaillais avec une réponse de cette question et avait un ami à l’améliorer ! Si elle est ici :

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X