Supprimer des éléments vides d'un tableau en Javascript

1145

Comment supprimer des éléments vides d'un tableau en JavaScript?

Existe-t-il un moyen simple ou dois-je le parcourir et les supprimer manuellement?

Tamas Czinege
la source
14
Il serait utile que votre question précise ce que vous entendez par «éléments vides», car la plupart des réponses ici interprètent cela de manière incorrecte (à mon humble avis) comme signifiant «éléments de falsey». NB: il y a une différence entre ce que vous obtenez var a = [,,]et var a = [undefined, undefined]. Le premier est vraiment vide, mais le second a en fait deux clés, mais avec des undefinedvaleurs.
Alnitak

Réponses:

1065

EDIT: Cette question a été répondue il y a près de neuf ans alors qu'il n'y avait pas beaucoup de méthodes intégrées utiles dans le Array.prototype.

Maintenant, certainement, je vous recommanderais d'utiliser la filterméthode.

Gardez à l'esprit que cette méthode vous renverra un nouveau tableau avec les éléments qui répondent aux critères de la fonction de rappel que vous lui fournissez.

Par exemple, si vous souhaitez supprimer des valeurs nullou undefined:

var array = [0, 1, null, 2, "", 3, undefined, 3,,,,,, 4,, 4,, 5,, 6,,,,];

var filtered = array.filter(function (el) {
  return el != null;
});

console.log(filtered);

Cela dépendra de ce que vous considérez comme "vide" par exemple, si vous avez affaire à des chaînes, la fonction ci-dessus ne supprimera pas les éléments qui sont une chaîne vide.

Un modèle typique que je vois souvent utilisé est d'éliminer les éléments qui sont falsy , qui comprennent une chaîne vide "", 0, NaN, null, undefinedet false.

Vous pouvez passer à la filterméthode, à la Booleanfonction constructeur ou renvoyer le même élément dans la fonction de critère de filtre, par exemple:

var filtered = array.filter(Boolean);

Ou

var filtered = array.filter(function(el) { return el; });

Dans les deux cas, cela fonctionne parce que la filterméthode dans le premier cas, appelle le Booleanconstructeur en tant que fonction, convertissant la valeur et dans le second cas, la filterméthode transforme en interne la valeur de retour du rappel implicitement en Boolean.

Si vous travaillez avec des tableaux clairsemés et que vous essayez de vous débarrasser des "trous", vous pouvez utiliser la filterméthode en passant un rappel qui renvoie vrai, par exemple:

var sparseArray = [0, , , 1, , , , , 2, , , , 3],
    cleanArray = sparseArray.filter(function () { return true });

console.log(cleanArray); // [ 0, 1, 2, 3 ]

Ancienne réponse: ne fais pas ça!

J'utilise cette méthode, étendant le prototype natif d'Array:

Array.prototype.clean = function(deleteValue) {
  for (var i = 0; i < this.length; i++) {
    if (this[i] == deleteValue) {         
      this.splice(i, 1);
      i--;
    }
  }
  return this;
};

test = new Array("", "One", "Two", "", "Three", "", "Four").clean("");
test2 = [1, 2,, 3,, 3,,,,,, 4,, 4,, 5,, 6,,,,];
test2.clean(undefined);

Ou vous pouvez simplement pousser les éléments existants dans un autre tableau:

// Will remove all falsy values: undefined, null, 0, false, NaN and "" (empty string)
function cleanArray(actual) {
  var newArray = new Array();
  for (var i = 0; i < actual.length; i++) {
    if (actual[i]) {
      newArray.push(actual[i]);
    }
  }
  return newArray;
}

cleanArray([1, 2,, 3,, 3,,,,,, 4,, 4,, 5,, 6,,,,]);
CMS
la source
110
AVERTISSEMENT: La 2e option supprimera tous les éléments d'un tableau considéré comme "falsifié", c'est-à-dire les valeurs de faux, 0, nul et non défini. Ce tableau se retrouverait avec rien du tout: [null ,,, 0, 0,0,0, false, null, 0] même si je voudrais les éléments avec des valeurs de 0, comme dans ce tableau: [ 1,0,1,0,0,1]
Jason Bunting
5
Je m'en rends compte - c'est pourquoi je n'ai parlé que de la deuxième option. Quant au premier, il est d'une portée si étroite que j'hésiterais à l'intégrer au prototype de l'Array. Voir la réponse d'Alnitak sur cette page pour quelque chose qui serait plus idéal. Le vôtre permet cependant d'enchaîner, évidemment.
Jason Bunting
1
Votre première solution est vraiment sympa si vous n'avez pas accès à la méthode "filter". Sinon, je pense que la réponse d'Alnitak est meilleure.
Joe Pineda
2
@AlfaTek - dans l'ensemble, à l'exception des navigateurs les plus récents, # 2 aura les meilleures performances, car les tableaux dans JS ne sont pas vraiment des tableaux. L' spliceappel est vraiment cher sur les anciens navigateurs car ils doivent renuméroter toutes les clés du tableau pour combler l'écart.
Alnitak
1
@David non, dans le code moderne, vous devez étendre en toute sécurité enArray.prototype utilisant Object.definePropertypour faire de la nouvelle fonction une propriété non énumérable , puis éviter les performances affectées par l'insertion .hasOwnPropertyde chaque boucle.
Alnitak
1382

Des moyens simples:

var arr = [1,2,,3,,-3,null,,0,,undefined,4,,4,,5,,6,,,,];


arr.filter(n => n)
// [1, 2, 3, -3, 4, 4, 5, 6]

arr.filter(Number) 
// [1, 2, 3, -3, 4, 4, 5, 6]

arr.filter(Boolean) 
// [1, 2, 3, -3, 4, 4, 5, 6]

ou - (uniquement pour les éléments de tableau simples de type "texte")

['','1','2',3,,'4',,undefined,,,'5'].join('').split(''); 
// output:  ["1","2","3","4","5"]

ou - Méthode classique: itération simple

var arr = [1,2,null, undefined,3,,3,,,0,,,[],,{},,5,,6,,,,],
    len = arr.length, i;

for(i = 0; i < len; i++ )
    arr[i] && arr.push(arr[i]);  // copy non-empty values to the end of the array

arr.splice(0 , len);  // cut the array and leave only the non-empty values

arr // [1,2,3,3,[],Object{},5,6]


via jQuery:

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

arr = $.grep(arr,function(n){ return n == 0 || n });

arr // [1, 2, 3, 3, 0, 4, 4, 5, 6]


MISE À JOUR - juste un autre moyen rapide et cool (en utilisant ES6):

var arr = [1,2,null, undefined,3,,3,,,0,,,4,,4,,5,,6,,,,], 
    temp = [];

for(let i of arr)
    i && temp.push(i); // copy each non-empty value to the 'temp' array

arr = temp;

arr // [1, 2, 3, 3, 4, 4, 5, 6]

Supprimer les valeurs vides

['foo', '',,,'',,null, ' ', 3, true, [], [1], {}, undefined, ()=>{}].filter(String)

// ["foo", null, " ", 3, true, [1], Object {}, undefined, ()=>{}]
vsync
la source
34
la première prise en charge d'IE pour le filtre est le mode standard IE9.
yincrash
14
pour le javascript pur, cela devrait êtrearr = arr.filter(function(n){return n; });
ilumin
19
foo.join("").split("")ne semble fonctionner que si les chaînes sont des caractères uniques
Atav32
9
Votre code JavaScript pur a un bug. Si le tableau contient une valeur avec "0", la valeur sera filtrée car "0" est faux. Ce que vous voulez, c'est: arr.filter (function (n) {return (n! == undefined && n! == null);});
John Kurlak
5
ES6 peut le faire encore plus simplement arr.filter(e=>e)et cela peut être enchaîné par carte, réduire, etc.
Sheepy
242

Si vous devez supprimer TOUTES les valeurs vides ("", null, non défini et 0):

arr = arr.filter(function(e){return e}); 

Pour supprimer des valeurs vides et des sauts de ligne:

arr = arr.filter(function(e){ return e.replace(/(\r\n|\n|\r)/gm,"")});

Exemple:

arr = ["hello",0,"",null,undefined,1,100," "]  
arr.filter(function(e){return e});

Revenir:

["hello", 1, 100, " "]

MISE À JOUR (basée sur le commentaire d'Alnitak)

Dans certaines situations, vous souhaiterez peut-être conserver "0" dans le tableau et supprimer tout le reste (null, non défini et ""), c'est une façon:

arr.filter(function(e){ return e === 0 || e });

Revenir:

["hello", 0, 1, 100, " "]
lepe
la source
Ouais c'est sympa car "" retire aussi "".
Vladimirs
3
La fonction de test pourrait être un peu plus explicite:function(e){return !!e}
Koen.
4
@Koen Veuillez noter que !!ecela inclura NaN (contrairement à 0) où enon (comme 0).
Sheepy
Ne répond pas réellement à la question posée.
Alnitak
2
OU l'utilisation var myarr=[1, 2,, 3,, 3,undefined,,"",,0, 4,, 4,, 5,, 6,,,,].filter(Boolean);supprime undefined, "" et 0
Mark Schultheiss
134

Un seul revêtement:

[1, false, "", undefined, 2].filter(Boolean); // [1, 2]

ou en utilisant underscorejs.org :

_.filter([1, false, "", undefined, 2], Boolean); // [1, 2]
// or even:
_.compact([1, false, "", undefined, 2]); // [1, 2]
andlrc
la source
1
C'est vraiment cool - j'ai une nouvelle question cependant: on dirait que vous utilisez un nom de classe comme appel de fonction - est-ce que le transtypage? Je n'ai jamais vu cela auparavant et je ne suis pas sûr de comprendre pourquoi le passage Booleanfonctionne en fonction ...
Andrew
8
Si vous traitez Booleancomme une fonction, elle retournera simplement trueou falsesi la valeur est vraiment / fausse.
andlrc
8
Vous ne traitez pas Boolean comme une fonction; il est une fonction. (Une fonction tout à fait normale, sauf qu'elle est implémentée en mode natif.) Quelqu'un doit faire quelques recherches sur le modèle d'objet JavaScript. ;)
ELLIOTTCABLE
@ELLIOTTCABLE Im juste va laisser ça ici, (true).constructor === Boolean. Et puis dites-moi si nous pouvons le faire avec d'autres build-ins dans JS. ;)) (bien sûr exclu les 5 autres constructeurs intégrés. (String, Array, Object, Function, Number))
andlrc
1
Échouera les deux s'il y a une valeur 0 dans le tableau
Sai Ram
129

Si vous avez Javascript 1.6 ou une version ultérieure, vous pouvez utiliser Array.filterune return truefonction de rappel triviale , par exemple:

arr = arr.filter(function() { return true; });

car .filtersaute automatiquement les éléments manquants dans le tableau d'origine.

La page MDN liée ci-dessus contient également une belle version de vérification des erreurs filterqui peut être utilisée dans les interpréteurs JavaScript qui ne prennent pas en charge la version officielle.

Notez que cela ne supprimera pas les nullentrées ni les entrées avec une undefinedvaleur explicite , mais l'OP a spécifiquement demandé des entrées "manquantes".

Alnitak
la source
Tu as raison! Cela peut être aussi simple que cela (et ça marche!): Test3 = [1,2,, 3,, 3 ,,,, 7 ,,, 7 ,,, 0 ,,, 4,, 4,, 5 ,, 6,, undefined ,, null ,,]; printp ("Utilisation du filtrage natif du tableau:", test3.filter (function (value) {return (value == undefined)? 0: 1;}));
Joe Pineda
3
+1 Comme l'a dit Alnitak, ils ont le code qui peut être utilisé dans le cas où js 1.6 n'est pas disponible
Sameer Alibhai
3
@katsh, j'ai clarifié - le code ci - dessus fonctionne pour supprimer les entrées pour lesquelles aucune valeur n'existe du tout, qui (j'ai par la suite) appris est sémantiquement différente du cas d'une clé qui existe mais qui a undefinedpour valeur donnée.
Alnitak
4
Pour supprimer les entrées non définies ou nulles, faites juste une petite modification ... arr = arr.filter (function (v) {return v;});
Alan CN
4
@AlanCN vous avez complètement manqué mon point. Le PO a demandé de supprimer les entrées manquantes , tandis que l'essentiel des réponses ici (incorrectement) supprime toutes les entrées "falsey".
Alnitak
65

Pour retirer les trous, vous devez utiliser

arr.filter(() => true)
arr.flat(0) // Currently stage 3, check compatibility before using this

Pour supprimer les valeurs de trou et de falsification (null, indéfini, 0, -0, NaN, "", false, document.all):

arr.filter(x => x)

Pour supprimer le trou, nul et non défini:

arr.filter(x => x != null)

arr = [, null, (void 0), 0, -0, NaN, false, '', 42];
console.log(arr.filter(() => true)); // [null, (void 0), 0, -0, NaN, false, '', 42]
console.log(arr.filter(x => x)); // [42]
console.log(arr.filter(x => x != null)); // [0, -0, NaN, false, "", 42]

tsh
la source
3
Cela devrait être haut dans la réponse. Pouvez-vous développer ce que vous entendez par trous / trou ..?
samayo
2
Les trous @samayo sont des éléments du tableau non remplis, c'est-à[, ,]
Jimmy Obonyo Abor
En utilisant arr.filter(x => x), JS vérifiera si x est véridique ou faux, c'est if (x)-à- dire que seule la valeur véridique sera affectée à la nouvelle liste.
KuanYu Chu
56

La manière propre de le faire.

var arr = [0,1,2,"Thomas","false",false,true,null,3,4,undefined,5,"end"];
arr = arr.filter(Boolean);
// [1, 2, "Thomas", "false", true, 3, 4, 5, "end"]
Tomás Senart
la source
5
Les éléments vides sont undefined; cela supprime essentiellement toutes les valeurs de falsification.
pimvdb
33

ES6 simple

['a','b','',,,'w','b'].filter(v => v);
ML13
la source
1
Cela ne fonctionne pas: [1, 'two', null, undefined, , NaN, false, true, 0].filter(v => v).
fermeture éclair
22

Avec Underscore / Lodash:

Cas d'utilisation général:

_.without(array, emptyVal, otherEmptyVal);
_.without([1, 2, 1, 0, 3, 1, 4], 0, 1);

Avec des vides:

_.without(['foo', 'bar', '', 'baz', '', '', 'foobar'], '');
--> ["foo", "bar", "baz", "foobar"]

Voir la documentation de lodash sans .

c4ourself
la source
Le problème avec #compact est qu'il supprime toutes les valeurs fausses. Donc, si votre tableau contient 0 valeur, elles seront également supprimées.
Samuel Brandão
21

ES6Méthode des versions justes et plus récentes, supposons que le tableau est ci-dessous:

 const arr = [1,2,3,undefined,4,5,6,undefined,7,8,undefined,undefined,0,9];

Manière simple:

 const clearArray = arr.filter( i => i );
AmerllicA
la source
16

Si l'utilisation d'une bibliothèque est une option, je sais que underscore.js a une fonction appelée compact () http://documentcloud.github.com/underscore/ il a également plusieurs autres fonctions utiles liées aux tableaux et aux collections.

Voici un extrait de leur documentation:

_.compact (tableau)

Renvoie une copie du tableau avec toutes les valeurs de falsification supprimées. En JavaScript, false, null, 0, "", undefined et NaN sont tous fausses.

_.compact ([0, 1, faux, 2, '', 3]);

=> [1, 2, 3]

Luis Perez
la source
Il supprime également les éléments non vides définis comme les éléments 0.
Timothy Gu
15

@Alnitak

En fait, Array.filter fonctionne sur tous les navigateurs si vous ajoutez du code supplémentaire. Voir ci-dessous.

var array = ["","one",0,"",null,0,1,2,4,"two"];

function isempty(x){
if(x!=="")
    return true;
}
var res = array.filter(isempty);
document.writeln(res.toJSONString());
// gives: ["one",0,null,0,1,2,4,"two"]  

C'est le code que vous devez ajouter pour IE, mais le filtre et la programmation fonctionnelle valent la peine.

//This prototype is provided by the Mozilla foundation and
//is distributed under the MIT license.
//http://www.ibiblio.org/pub/Linux/LICENSES/mit.license

if (!Array.prototype.filter)
{
  Array.prototype.filter = function(fun /*, thisp*/)
  {
    var len = this.length;
    if (typeof fun != "function")
      throw new TypeError();

    var res = new Array();
    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in this)
      {
        var val = this[i]; // in case fun mutates this
        if (fun.call(thisp, val, i, this))
          res.push(val);
      }
    }

    return res;
  };
}
Erik Johansson
la source
Cela devrait être la réponse acceptée, car cela fonctionne hors de la boîte. Merci beaucoup.
Tony
@Tony non, ce ne devrait pas être le cas, car un élément contenant une chaîne vide n'est pas la même chose qu'un "élément vide", ce dernier étant ce que l'OP a demandé.
Alnitak
14

Étant donné que personne d'autre ne l'a mentionné et que la plupart des gens ont souligné dans leur projet, vous pouvez également utiliser _.without(array, *values);.

_.without(["text", "string", null, null, null, "text"], null)
// => ["text", "string", "text"]
Josh Bedo
la source
12

ES6:

let newArr = arr.filter(e => e);
Kanan Farzali
la source
8

Vous trouverez peut-être plus facile de boucler sur votre tableau et de créer un nouveau tableau à partir des éléments que vous souhaitez conserver du tableau qu'en essayant de boucler et d'épisser comme cela a été suggéré, depuis la modification de la longueur du tableau pendant qu'il est en boucle plus peut introduire des problèmes.

Vous pourriez faire quelque chose comme ça:

function removeFalsyElementsFromArray(someArray) {
    var newArray = [];
    for(var index = 0; index < someArray.length; index++) {
        if(someArray[index]) {
            newArray.push(someArray[index]);
        }
    }
    return newArray;
}

En fait, voici une solution plus générique:

function removeElementsFromArray(someArray, filter) {
    var newArray = [];
    for(var index = 0; index < someArray.length; index++) {
        if(filter(someArray[index]) == false) {
            newArray.push(someArray[index]);
        }
    }
    return newArray;
}

// then provide one or more filter functions that will 
// filter out the elements based on some condition:
function isNullOrUndefined(item) {
    return (item == null || typeof(item) == "undefined");
}

// then call the function like this:
var myArray = [1,2,,3,,3,,,,,,4,,4,,5,,6,,,,];
var results = removeElementsFromArray(myArray, isNullOrUndefined);

// results == [1,2,3,3,4,4,5,6]

Vous avez l'idée - vous pourriez alors avoir d'autres types de fonctions de filtre. Probablement plus que ce dont vous avez besoin, mais je me sentais généreux ...;)

Jason Bunting
la source
7

Qu'en est-il (ES6): pour supprimer la valeur Falsy d'un tableau.

var arr = [0,1,2,"test","false",false,true,null,3,4,undefined,5,"end"];

arr.filter((v) => (!!(v)==true));

//output:

//[1, 2, "test", "false", true, 3, 4, 5, "end"]
VIJAY P
la source
6

Vous devez utiliser le filtre pour obtenir un tableau sans éléments vides. Exemple sur ES6

const array = [1, 32, 2, undefined, 3];
const newArray = array.filter(arr => arr);
Gapur Kassym
la source
3

Je suis tout simplement ajouter ma voix au - dessus de « appel ES5 de Array..filter()avec un constructeur mondial » golf-hack, mais je suggère d' utiliser au Objectlieu de String, Booleanou Numbercomme suggéré ci - dessus.

Plus précisément, les ES5 filter()ne se déclenchent pas déjà pour les undefinedéléments du tableau; donc une fonction qui renvoie universellement true, qui retourne tous les éléments filter()hits, ne retournera nécessairement que des non- undefinedéléments:

> [1,,5,6,772,5,24,5,'abc',function(){},1,5,,3].filter(function(){return true})
[1, 5, 6, 772, 5, 24, 5, 'abc', function (){}, 1, 5, 3]

Cependant, l'écriture ...(function(){return true;})est plus longue que l'écriture ...(Object); et la valeur de retour du Objectconstructeur sera, en toutes circonstances , une sorte d'objet. Contrairement aux constructeurs de boxe primitifs suggérés ci-dessus, aucune valeur d'objet possible n'est falsey, et donc dans un cadre booléen, Objectest un raccourci pour function(){return true}.

> [1,,5,6,772,5,24,5,'abc',function(){},1,5,,3].filter(Object)
[1, 5, 6, 772, 5, 24, 5, 'abc', function (){}, 1, 5, 3]
ELLIOTTCABLE
la source
1
ATTENTION: filter (String) et filter (Object) ne filtrent pas les valeurs nulles ou numériques. Parce qu'un constructeur est également une fonction, vous pouvez passer String à filtrer, c'est-à-dire qu'il someArray.filter(String);est en fait équivalent à someArray.filter(function(x){ return String(x); });. Si vous souhaitez supprimer toutes les valeurs de falsification, vous pouvez someArray.filter(Boolean);supprimer 0, -0, NaN, false, '', null et indéfini.
robocat
1
Belle réponse, bien que je m'interroge sur la surcharge de performances d'appeler le Objectconstructeur par opposition à la return trueméthode. @robocat l'OP a demandé que les éléments vides soient supprimés, pas les valeurs nulles.
Alnitak
Je préfère la solution la plus courte et la plus claire, sauf dans les boucles serrées. Préférence personnelle, je suppose. (=
ELLIOTTCABLE
3

Lors de l'utilisation de la réponse la plus votée ci-dessus, premier exemple, j'obtenais des caractères individuels pour des longueurs de chaîne supérieures à 1. Ci-dessous est ma solution à ce problème.

var stringObject = ["", "some string yay", "", "", "Other string yay"];
stringObject = stringObject.filter(function(n){ return n.length > 0});

Au lieu de ne pas revenir si indéfini, nous retournons si la longueur est supérieure à 0. J'espère que cela aide quelqu'un là-bas.

Retour

["some string yay", "Other string yay"]
John Miller
la source
+1 car c'est très pratique et c'est exactement ce dont j'ai généralement besoin pour travailler avec des tableaux de chaînes, mais sachez que cela supprime les nombres (s'ils ne sont pas sous forme de chaîne) car ils n'ont pas de .lenghth donc, ["", "some string yay", "", "", 123, "Other string yay"].filter(function(n){ return n.length > 0}) //gives your same result removing 123Remplacer cette fonction. .. avec String, ironiquement, laisse des nombres mais donnerait le même résultat dans votre tableau donné.
aamarks
3
var data = [null, 1,2,3];
var r = data.filter(function(i){ return i != null; })

console.log(r) 

[1,2,3]

KARTHIKEYAN.A
la source
C'est la manière évidemment correcte de le faire et devrait être au top!
Martin Andersson
2

Que dire de cela:

js> [1,2,,3,,3,,,0,,,4,,4,,5,,6,,,,].filter(String).join(',')
1,2,3,3,0,4,4,5,6
JessyNinja
la source
6
join() === join(','):)
pimvdb
1

Cela fonctionne, je l'ai testé dans AppJet (vous pouvez copier-coller le code sur son IDE et appuyer sur "recharger" pour le voir fonctionner, pas besoin de créer de compte)

/* appjet:version 0.1 */
function Joes_remove(someArray) {
    var newArray = [];
    var element;
    for( element in someArray){
        if(someArray[element]!=undefined ) {
            newArray.push(someArray[element]);
        }
    }
    return newArray;
}

var myArray2 = [1,2,,3,,3,,,0,,,4,,4,,5,,6,,,,];

print("Original array:", myArray2);
print("Clenased array:", Joes_remove(myArray2) );
/*
Returns: [1,2,3,3,0,4,4,5,6]
*/
Joe Pineda
la source
1
Cela ne semble fonctionner que "par accident", car c'est le fait d'énumérer les clés via for ... inqui provoque en fait le saut des éléments manquants. Le test de undefinedsert uniquement à supprimer les éléments réels qui sont explicitement définis sur cette valeur.
Alnitak
1

Une autre façon de le faire est de tirer parti de la propriété length du tableau: empaquetez les éléments non nuls sur la «gauche» du tableau, puis réduisez la longueur. Il s'agit d'un algorithme sur place - n'alloue pas de mémoire, tant pis pour le garbage collector -, et il a un très bon comportement meilleur / moyen / pire cas.

Cette solution, par rapport aux autres ici, est entre 2 à 50 fois plus rapide sur Chrome, et 5 à 50 fois plus rapide sur Firefox, comme vous pouvez le voir ici: http://jsperf.com/remove-null-items-from-array

Le code ci-dessous ajoute la méthode «removeNull» non énumérable au tableau, qui renvoie «this» pour la connexion en guirlande:

var removeNull = function() {
    var nullCount = 0           ;
    var length    = this.length ;
    for (var i=0, len=this.length; i<len; i++) { if (!this[i]) {nullCount++} }
    // no item is null
    if (!nullCount) { return this}
    // all items are null
    if (nullCount == length) { this.length = 0; return this }
    // mix of null // non-null
    var idest=0, isrc=length-1;
    length -= nullCount ;                
    while (true) {
         // find a non null (source) slot on the right
         while (!this[isrc])  { isrc--; nullCount--; } 
         if    (!nullCount) { break }       // break if found all null
         // find one null slot on the left (destination)
         while ( this[idest]) { idest++  }  
         // perform copy
         this[idest]=this[isrc];
         if (!(--nullCount)) {break}
         idest++;  isrc --; 
    }
    this.length=length; 
    return this;
};  

Object.defineProperty(Array.prototype, 'removeNull', 
                { value : removeNull, writable : true, configurable : true } ) ;
GameAlchemist
la source
Belle réponse, même s'il serait bien de voir quelques cas de test pour le montrer en action!
Alnitak
2
Cette réponse est très fascinante mais un peu me fait penser à regarder un ordinateur construit en 1945 quand j'ai un smartphone: arr.filter(e => e).
agm1984
@ agm1984 votre smartphone n'est pas intelligent
Hernán Eche
Cela peut dépendre de votre définition de smart- comme le verbe, pour provoquer une forte douleur cuisante. Cela est pertinent en raison de la douleur physique si j'arme mon téléphone en raison de votre commentaire.
agm1984
1
foo = [0, 1, 2, "", , false, 3, "four", null]

foo.filter(function(e) {
    return e === 0 ? '0' : e
})

Retour

[0, 1, 2, 3, "four"]
sqram
la source
1

'Utilisation abusive' de la boucle for ... in (objet-membre). => Seules les valeurs véridiques apparaissent dans le corps de la boucle.

// --- Example ----------
var field = [];

field[0] = 'One';
field[1] = 1;
field[3] = true;
field[5] = 43.68;
field[7] = 'theLastElement';
// --- Example ----------

var originalLength;

// Store the length of the array.
originalLength = field.length;

for (var i in field) {
  // Attach the truthy values upon the end of the array. 
  field.push(field[i]);
}

// Delete the original range within the array so that
// only the new elements are preserved.
field.splice(0, originalLength);
michael.zech
la source
le code est correct, le commentaire est faux. L'acte d'utiliser for ... inest ce qui supprime les clés non définies du tableau, mais vous n'avez en fait aucun code ici pour accepter autrement uniquement les valeurs "véridiques"
Alnitak
1

Cela pourrait vous aider: https://lodash.com/docs/4.17.4#remove

var details = [
            {
                reference: 'ref-1',
                description: 'desc-1',
                price: 1
            }, {
                reference: '',
                description: '',
                price: ''
            }, {
                reference: 'ref-2',
                description: 'desc-2',
                price: 200
            }, {
                reference: 'ref-3',
                description: 'desc-3',
                price: 3
            }, {
                reference: '',
                description: '',
                price: ''
            }
        ];

        scope.removeEmptyDetails(details);
        expect(details.length).toEqual(3);

scope.removeEmptyDetails = function(details){
            _.remove(details, function(detail){
                return (_.isEmpty(detail.reference) && _.isEmpty(detail.description) && _.isEmpty(detail.price));
            });
        };
Sandeep M
la source
1
var data= { 
    myAction: function(array){
        return array.filter(function(el){
           return (el !== (undefined || null || ''));
        }).join(" ");
    }
}; 
var string = data.myAction(["I", "am","", "working", "", "on","", "nodejs", "" ]);
console.log(string);

Production:

Je travaille sur nodejs

Il supprimera l'élément vide du tableau et affichera un autre élément.

Jitendra virani
la source
sortie: «Je travaille sur nodejs». il supprimera l'élément vide du tableau et affichera un autre élément.
Jitendra virani
J'ai amélioré ta réponse. S'il vous plaît essayez de faire une réponse simple, claire et lisible;)
GGO
1

Suppression de tous les éléments vides

Si un tableau contient des objets, des tableaux et des chaînes vides à côté d'autres éléments vides, nous pouvons les supprimer avec:

const arr = [ [], ['not', 'empty'], {}, { key: 'value' }, 0, 1, null, 2, "", "here", " ", 3, undefined, 3, , , , , , 4, , 4, , 5, , 6, , , ]

let filtered = JSON.stringify(
  arr.filter((obj) => {
    return ![null, undefined, ''].includes(obj)
  }).filter((el) => {
    return typeof el != "object" || Object.keys(el).length > 0
  })
)

console.log(JSON.parse(filtered))

Compactage simple (suppression des éléments vides d'un tableau)

Avec ES6:

const arr = [0, 1, null, 2, "", 3, undefined, 3, , , , , , 4, , 4, , 5, , 6, , , ,]

let filtered = arr.filter((obj) => { return ![null, undefined].includes(obj) })

console.log(filtered)

Avec Javascript simple ->

var arr = [0, 1, null, 2, "", 3, undefined, 3, , , , , , 4, , 4, , 5, , 6, , , ,]

var filtered = arr.filter(function (obj) { return ![null, undefined].includes(obj) })

console.log(filtered)

Zlatko Alomerovic
la source
0

Filtrer les entrées non valides avec une expression régulière

array = array.filter(/\w/);
filter + regexp
lcabral
la source
Est-ce que ça marche? il montre une erreur TypeError: [objet RegExp] n'est pas une fonction
FreeLightman
0

La meilleure façon de supprimer les éléments vides est d'utiliser Array.prototype.filter(), comme déjà mentionné dans d'autres réponses.

Malheureusement, Array.prototype.filter()n'est pas pris en charge par IE <9. Si vous devez toujours prendre en charge IE8 ou une version encore plus ancienne d'IE, vous pouvez utiliser le polyfill suivant pour ajouter la prise Array.prototype.filter()en charge de ces navigateurs:

if (!Array.prototype.filter) {
  Array.prototype.filter = function(fun/*, thisArg*/) {
    'use strict';
    if (this === void 0 || this === null) {
      throw new TypeError();
    }
    var t = Object(this);
    var len = t.length >>> 0;
    if (typeof fun !== 'function') {
      throw new TypeError();
    }
    var res = [];
    var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
    for (var i = 0; i < len; i++) {
      if (i in t) {
        var val = t[i];
        if (fun.call(thisArg, val, i, t)) {
          res.push(val);
        }
      }
    }
    return res;
  };
}
John Slegers
la source