web-dev-qa-db-fra.com

Le moyen le plus efficace de convertir une collection HTMLC en tableau

Existe-t-il un moyen plus efficace de convertir une collection HTMLC en un tableau, outre le fait d'itérer le contenu de cette collection et de placer manuellement chaque élément dans un tableau?

316
Tom
var arr = Array.prototype.slice.call( htmlCollection )

aura le même effet en utilisant un code "natif".

Modifier

Comme cela suscite beaucoup de points de vue, notez (selon le commentaire de @ oriol) que l'expression plus concise suivante est équivalente :

var arr = [].slice.call(htmlCollection);

Mais notez, selon le commentaire de @ JussiR, que contrairement au formulaire "verbose", il crée une instance de tableau vide, inutilisée et inutilisable dans le processus. Ce que les compilateurs font à ce sujet n’est pas connu du programmeur.

Modifier

Depuis ECMAScript 2015 (ed 6), il y a aussi Array.from :

var arr = Array.from(htmlCollection);

Modifier

ECMAScript 2015 fournit également le opérateur de propagation , qui est fonctionnellement équivalent à Array.from (bien que notez que Array.from prend en charge une fonction de mappage comme second argument).

var arr = [...htmlCollection];

J'ai confirmé que les deux travaux ci-dessus fonctionnent sur NodeList.

569
harpo

je ne sais pas si c'est le plus efficace, mais une syntaxe ES6 concise pourrait être:

let arry = [...htmlCollection] 

Edit: Un autre commentaire de Chris_F:

let arry = Array.from(htmlCollection)
77
mido

J'ai vu une méthode plus concise pour obtenir Array.prototype méthodes en général qui fonctionne tout aussi bien. La conversion d'un objet HTMLCollection en un objet Array est illustrée ci-dessous:

 []. slice.call (votreHTMLCollectionObject); 

Et, comme mentionné dans les commentaires, pour les anciens navigateurs tels que IE7 et les versions antérieures, , vous devez simplement utiliser une fonction de compatibilité, comme par exemple:

function toArray(x) {
    for(var i = 0, a = []; i < x.length; i++)
        a.Push(x[i]);

    return a
}

Je sais que c’est une vieille question, mais j’ai senti que la réponse acceptée était un peu incomplète; alors j'ai pensé jeter ceci dehors là FWIW.

19
Codesmith

Pour une implémentation multi-navigateurs, je vous conseillerais de regarder prototype.js$A function

copie de 1.6.1 :

function $A(iterable) {
  if (!iterable) return [];
  if ('toArray' in Object(iterable)) return iterable.toArray();
  var length = iterable.length || 0, results = new Array(length);
  while (length--) results[length] = iterable[length];
  return results;
}

Il n'utilise pas Array.prototype.slice probablement parce qu'il n'est pas disponible sur tous les navigateurs. Je crains que la performance ne soit vraiment mauvaise, car la solution de repli est une boucle javascript sur la iterable.

6
Gareth Davis

Ceci est ma solution personnelle, basée sur les informations ici (ce fil):

var Divs = new Array();    
var Elemns = document.getElementsByClassName("divisao");
    try {
        Divs = Elemns.prototype.slice.call(Elemns);
    } catch(e) {
        Divs = $A(Elemns);
    }

Où $ A a été décrit par Gareth Davis dans son message:

function $A(iterable) {
  if (!iterable) return [];
  if ('toArray' in Object(iterable)) return iterable.toArray();
  var length = iterable.length || 0, results = new Array(length);
  while (length--) results[length] = iterable[length];
  return results;
}

Si le navigateur prend en charge la meilleure façon, ok, sinon, utilisera le navigateur croisé.

3
Gustavo

Cela fonctionne dans tous les navigateurs, y compris les versions antérieures IE.

var arr = [];
[].Push.apply(arr, htmlCollection);

Puisque jsperf est toujours en panne pour le moment, voici un jsfiddle qui compare les performances de différentes méthodes. https://jsfiddle.net/qw9qf48j/

3
Nicholas

Pour convertir efficacement tableau en tableau, nous pouvons utiliser le jQuerymakeArray:

makeArray: Convertit un objet semblable à un tableau en un véritable tableau JavaScript.

Usage:

var domArray = jQuery.makeArray(htmlCollection);

Un petit extra:

Si vous ne souhaitez pas conserver de référence à l'objet tableau (la plupart du temps, les modifications HTMLCollections sont dynamiques, il est donc préférable de les copier dans un autre tableau. Cet exemple porte une attention particulière aux performances:

var domDataLength = domData.length //Better performance, no need to calculate every iteration the domArray length
var resultArray = new Array(domDataLength) // Since we know the length its improves the performance to declare the result array from the beginning.

for (var i = 0 ; i < domDataLength ; i++) {
    resultArray[i] = domArray[i]; //Since we already declared the resultArray we can not make use of the more expensive Push method.
}

Qu'est-ce qu'un tableau?

HTMLCollection est un objet "array-like", les objets ressemblant à un tablea sont similaires à l'objet du tableau, mais il manque une grande partie de sa définition fonctionnelle:

Les objets ressemblant à des tableaux ressemblent à des tableaux. Ils ont divers éléments numérotés et une propriété de longueur. Mais c’est là que la similitude s’arrête. Les objets de type tableau n’ont aucune des fonctions de tableau, et les boucles for-in ne fonctionnent même pas!

3
Shahar Shokrani