Compter les valeurs vides en tableau

Compte tenu d'un tableau:

var arr = [1,,2,5,6,,4,5,6,,]; 

Comptez le nombre de valeurs vides : (longueur – longueur après avoir supprimé les valeurs vides)

 var empties = arr.length - arr.filter(function(x){ return true }).length; // return 3 

ou quelque chose comme ça

 arr.empties = arr.length; arr.forEach(function(x){ arr.empties-- }); // arr.empties returns 3 

Est-ce la meilleure façon ou est-ce que je manque quelque chose?

Selon vos commentaires sur une autre réponse, il vous semble que vous êtes après la méthode la plus courte. Eh bien, vous voudrez peut-être considérer une variante de votre propre exemple:

 var empties = arr.length - arr.filter(String).length; 

Tout ce que vous faites est de passer une fonction native plutôt que d'une fonction anonyme, en économisant quelques octets précieux. Tout constructeur ou fonction natif fera, tant qu'il ne renverra pas un booléen.


Vous devez être plus précis sur ce que vous considérerez comme la «meilleure façon». Par exemple, certaines méthodes donneront de meilleures performances que d'autres, certaines sont plus concises et certaines ont une meilleure compatibilité.

Les solutions que vous mentionnez dans la publication exigent que les navigateurs soient compatibles avec la spécification ECMAScript 5ème édition, donc ils ne fonctionneront pas dans certains navigateurs plus anciens (lire: IE8 et plus bas).

La «meilleure» approche globale est une boucle simple. Ce n'est pas aussi concis que vos méthodes, mais ce sera sans aucun doute le plus rapide et le plus compatible:

 var arr = [1,,2,5,6,,4,5,6,,], count = 0, i = arr.length; while (i--) { if (typeof arr[i] === "undefined") count++; } 

Cela utilise les optimisations de boucle (l'utilisation de la durée et de la décrémentation est plus rapide que for ).

Une autre approche serait de trier le tableau de sorte que les éléments undefined soient tous à la fin et utilisent une boucle pour itérer à l'arrière:

 var arr = [1,,2,5,6,,4,5,6,,], count = 0; arr.sort(); while (typeof arr.pop() === "undefined") count++; alert(count); //-> 3 

Cette approche modifie le tableau d'origine et supprime les éléments qui peuvent ne pas être ce que vous voulez. Cependant, il peut être beaucoup plus rapide sur des tableaux très volumineux.

Ensemble de test de performance
http://jsperf.com/count-undefined-array-elements

Cela me semble correct.

Vous pourriez également faire:

 var empties = arr.reduce(function(x, y){ return x-1; }, arr.length); 

En outre, si cela ne vous dérange pas de trier le tableau, vous pourriez obtenir un peu de performance supplémentaire:

 arr.sort(); for (var j=arr.length-1; j > 0 && arr[j] === undefined; j--) {} var empties = arr.length-j-1; 

Ou, sans utiliser js 1.6 filter / foreach, vous pouvez le cycliser de cette façon:

 var arr = [1,,2,5,6,,4,5,6,,]; var emptyElems = 0; for(var i=0, l = arr.length; i < l; i++){ emptyLength += (arr[i] === undefined) ? 1 : 0; } alert(emptyElems); //alerts 3