Question

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

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

Était-ce utile?

La solution

MODIFIER: Cette question a reçu une réponse il y a presque 9 ans, alors qu'il n'y avait pas beaucoup de méthodes intégrées utiles dans le Array.prototype.

Maintenant, je vous recommanderais simplement d'utiliser la filter méthode.

Notez que cette méthode vous renverra un nouveau tableau avec les éléments qui transmettent les critères de la fonction de rappel que vous lui fournissez, par exemple si vous souhaitez supprimer null ou undefined valeurs:

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 supprimerait pas les éléments qui sont une chaîne vide.

Un schéma courant que je vois souvent utilisé consiste à supprimer les éléments falsy , qui incluent une chaîne vide "", 0, NaN, false, Boolean et <=>.

Vous pouvez simplement passer à la méthode <=>, à la fonction constructeur <=>, ou simplement renvoyer le même élément dans la fonction de filtre, par exemple:

var filtered = array.filter(Boolean);

Ou

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

Dans les deux cas, cela fonctionne car la méthode <=>, dans le premier cas, appelle le constructeur <=> en tant que fonction et convertit la valeur. Dans le second cas, la méthode <=> convertit en interne la valeur de retour de le rappel implicite à <=>.

Si vous travaillez avec des tableaux fragmentés et essayez de vous débarrasser des & "; trous &" ;, vous pouvez simplement utiliser la méthode <=> en passant un rappel qui retourne true, 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 faites pas ça!

J'utilise cette méthode pour étendre le prototype de tableau natif:

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,,,,]);

Autres conseils

Façons 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 des éléments de tableau uniques de type " texte ")

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

ou - Manière 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]


UPDATE - juste un autre moyen rapide et sympa (avec 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;
delete temp; // discard the variable

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, ()=>{}]

Si vous devez supprimer TOUTES les valeurs vides (" " ;, null, undefined and 0):

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

Pour supprimer les valeurs vides et les 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});

Retour:

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

UPDATE (basé sur le commentaire d'Alnitak)

Dans certaines situations, vous souhaiterez peut-être conserver " 0 " dans le tableau et supprimez tout le reste (null, undefined et & "; &";), ceci est un moyen:

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

Retour:

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

Une seule doublure:

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

ou avec underscorejs.org :

_.filter([1, false, "", undefined, 2], Boolean); // [1, 2]
// or even:
_.compact([1, false, "", undefined, 2]); // [1, 2]

Si vous avez Javascript 1.6 ou une version ultérieure, vous pouvez utiliser Array.filter à l'aide d'une fonction de rappel triviale return true , par exemple:

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

depuis .filter ignore automatiquement les éléments manquants dans le tableau d'origine.

La page MDN liée ci-dessus contient également une belle version de filtre permettant de vérifier les erreurs, qui 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 entrées null ni les entrées avec une valeur indéfinie explicite, mais l'OP a spécifiquement demandé "" manquant". entrées.

Pour éliminer les trous, vous devez utiliser

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

Pour supprimer les trous et les valeurs fausses (valeurs null, indéfinies, 0, -0, NaN, "false", document.all):

arr.filter(x => x)

Pour supprimer les trous, null et indéfinis:

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]

La façon 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"]

Simple ES6

['a','b','',,,'w','b'].filter(v => v);

Avec Underscore / Lodash:

Cas d'utilisation général:

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

Avec les vides:

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

Voir la documentation relative à lodash pour sans .

Seulement ES6 et les méthodes plus récentes, supposons que le tableau se trouve 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 );

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 comporte é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 faussement supprimées. En JavaScript, false, null, 0, "", indéfini et NaN sont tous des faussetés.

     

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

     

= > [1, 2, 3]

@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 la programmation par filtre et fonctionnelle vaut l’avantage.

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

Comme personne d'autre ne l'a mentionné et que la plupart des gens ont des traits de soulignement inclus dans leur projet, vous pouvez également utiliser _. without (array, * values); .

_.without(["text", "string", null, null, null, "text"], null)
// => ["text", "string", "text"]

Vous trouverez peut-être plus facile de boucler sur votre tableau et de construire un nouveau tableau à partir des éléments que vous souhaitez conserver dans le tableau plutôt que d'essayer de boucler et de fusionner comme cela a été suggéré, car vous pouvez modifier la longueur du tableau en boucle peut poser des problèmes.

Vous pouvez faire quelque chose comme ceci:

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 filtrage. Probablement plus que ce dont vous avez besoin, mais je me sentais généreux ...;)

ES6: let newArr = arr.filter(e => e);

Qu'en est-il de cela (ES6): 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"]

Utilisez filtre pour obtenir & nbsp; un tableau sans éléments vides. Exemple sur ES6

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

J'ajoute simplement ma voix à l'option ci-dessus "appelle le Array..filter () de l'ES5 avec un constructeur global" golf-hack, mais je suggère d'utiliser Objet . au lieu de String , Boolean ou Number comme suggéré ci-dessus.

Plus précisément, filter () d'ES5 ne déclenche déjà pas pour les éléments undefined dans le tableau; donc une fonction qui renvoie universellement true , qui renvoie tous les éléments filter () , ne renverra nécessairement que des éléments 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, écrire ... (function () {return true;}) est plus long que d'écrire ... (Object) ; et la valeur de retour du constructeur Object sera, sous aucune circonstance , une sorte d'objet. Contrairement aux constructeurs primitive-boxing suggérés ci-dessus, aucune valeur-objet possible n'est falsey, et dans un contexte booléen, Object est 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]

Lors de l’utilisation de la réponse la plus votée ci-dessus, premier exemple, je recevais des caractères individuels pour des longueurs de chaîne supérieures à 1. Vous trouverez ci-dessous la 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 non défini, nous le renvoyons si la longueur est supérieure à 0. J'espère que cela aidera quelqu'un.

Renvoie

["some string yay", "Other string yay"]
var data = [null, 1,2,3];
var r = data.filter(function(i){ return i != null; })
console.log(r) 
  

[1,2,3]

Qu'en est-il de cela:

js> [1,2,,3,,3,,,0,,,4,,4,,5,,6,,,,].filter(String).join(',')
1,2,3,3,0,4,4,5,6

Cela fonctionne, je l’ai testé dans AppJet (vous pouvez copier-coller le code sur son IDE et appuyer sur " ; rechargez "pour le voir fonctionner, vous n'avez pas besoin de créer un 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]
*/

Une autre façon de le faire consiste à tirer parti de la propriété length du tableau: placez les éléments non nuls à gauche du tableau, puis réduisez la longueur. Il s’agit d’un algorithme sur place (il n’alloue pas de mémoire, ce qui est dommage pour le ramasse-miettes) et il présente un très bon comportement dans le meilleur / moyen / pire cas.

Cette solution, comparée aux autres solutions ici, est 2 à 50 fois plus rapide sous Chrome et 5 à 50 fois plus rapide sous Firefox, comme vous pouvez le voir ici: http://jsperf.com/remove-null-items-from-array

Le code ci-dessous ajoute la méthode non énumérable "removeNull" au tableau, qui renvoie "this" pour un chaînage 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 } ) ;
foo = [0, 1, 2, "", , false, 3, "four", null]

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

renvoie

[0, 1, 2, 3, "four"]

'Abuser' de la boucle for ... in (membre de l'objet).   = > Seules les valeurs de vérité 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);

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

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

Sortie:

  

Je travaille sur nodejs

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

Filtrage des entrées non valides avec une expression régulière

array = array.filter(/\w/);
filter + regexp

Le meilleur moyen de supprimer les éléments vides consiste à utiliser Array.prototype.filter () , comme indiqué 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 pour ajouter la prise en charge de Array.prototype.filter () dans les navigateurs suivants:

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

Si quelqu'un souhaite nettoyer l'intégralité d'un tableau ou d'un objet, cela peut aider .

var qwerty = {
    test1: null,
    test2: 'somestring',
    test3: 3,
    test4: {},
    test5: {
        foo: "bar"
    },
    test6: "",
    test7: undefined,
    test8: " ",
    test9: true,
    test10: [],
    test11: ["77","88"],
    test12: {
        foo: "foo",
        bar: {
            foo: "q",
            bar: {
                foo:4,
                bar:{}
            }
        },
        bob: {}
    }
}

var asdfg = [,,"", " ", "yyyy", 78, null, undefined,true, {}, {x:6}, [], [2,3,5]];

function clean_data(obj) {
    for (var key in obj) {
        // Delete null, undefined, "", " "
        if (obj[key] === null || obj[key] === undefined || obj[key] === "" || obj[key] === " ") {
            delete obj[key];
        }
        // Delete empty object
        // Note : typeof Array is also object
        if (typeof obj[key] === 'object' && Object.keys(obj[key]).length <= 0) {
            delete obj[key];
        }
        // If non empty object call function again
        if(typeof obj[key] === 'object'){
            clean_data(obj[key]);
        }
    }
    return obj;
}

var objData = clean_data(qwerty);
console.log(objData);
var arrayData = clean_data(asdfg);
console.log(arrayData);

Résultat:

Supprime tout élément null , indéfini , "" ", " "quot , objet vide ou tableau vide

jsfiddle ici

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top