web-dev-qa-db-fra.com

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

Comment 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?

821
Tamas Czinege

EDIT: 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 méthode filter.

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

Je vois un modèle couramment utilisé qui consiste à supprimer les éléments falsy, qui incluent une chaîne vide "", 0, NaN, null, undefined et false.

Vous pouvez simplement passer à la méthode filter, à la fonction constructeur Boolean, ou simplement 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 car la méthode filter, dans le premier cas, appelle le constructeur Boolean en tant que fonction, convertissant la valeur, et dans le second cas, la méthode filter convertit en interne la valeur de retour du rappel implicitement en Boolean.

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

J'utilise cette méthode, en étendant le prototype natif 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,,,,]);
633
CMS

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 les éléments de tableau single de type "text")

['','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, ()=>{}]
1230
vsync

Si vous devez supprimer TOUTES les valeurs vides ("", null, non défini et 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});

Revenir:

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

UPDATE (basé sur le commentaire d'Alnitak)

Dans certaines situations, vous voudrez peut-être conserver "0" dans le tableau et supprimer tout le reste (null, indéfini et ""), par exemple:

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

Revenir:

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

Simplement une doublure:

[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]
127
andlrc

Si vous avez Javascript 1.6 ou une version ultérieure, vous pouvez utiliser Array.filter en utilisant une fonction de rappel return true triviale, par exemple:

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

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

La page MDN liée ci-dessus contient également une version agréable de filter qui permet de vérifier les erreurs et 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 undefined explicite, mais le terminal opérateur a spécifiquement demandé des entrées "manquantes".

116
Alnitak

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"]
51
Tomás Senart

Pour éliminer 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, falsy (valeurs null, indéfinies, 0, -0, NaN, "", false, document.all):

arr.filter(x => x)

Pour supprimer trou, null et indé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]

47
tsh

ES6 simple

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

Avec Underscore/Lodash:

Cas d'usage 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 documentation lodash pour sans .

20
c4urself

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/ , mais aussi 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 fausseté supprimées. En JavaScript, false, null, 0, "", indéfini et NaN sont tous de la fausseté.

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

=> [1, 2, 3]

15
Luis Perez

@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 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;
  };
}
14
Erik Johansson

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

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

Juste la méthode ES6 et les versions 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 );
11
AmerllicA

Vous trouverez peut-être plus facile de boucler sur votre tableau et de construire un nouveau tableau à partir des éléments que vous souhaitez garder du tableau plutôt que d'essayer de boucler et d'épisser comme cela a été suggéré, car vous modifiez la longueur du tableau pendant qu'il est en boucle. dessus peut introduire des problèmes.

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

8
Jason Bunting

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"]
6
VIJAY P

Vous devriez 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);
5
Gapur Kassym
var data = [null, 1,2,3];
var r = data.filter(function(i){ return i != null; })

console.log(r) 

[1,2,3]

3
KARTHIKEYAN.A

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. 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 indéfini, nous retournons si la longueur est supérieure à 0. J'espère que cela aidera quelqu'un.

Résultats

["some string yay", "Other string yay"]
3
John Miller

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

Plus précisément, le filter() de ES5 ne déclenche déjà pas d'éléments undefined dans le tableau; donc une fonction qui renvoie universellement true, qui retourne les hits all elements filter(), ne renverra nécessairement que des éléments non -undefined:

> [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 ...(Object); et la valeur de retour du constructeur Object sera, sous toutes circonstances , une sorte d'objet. Contrairement aux constructeurs de boxe primitifs suggérés ci-dessus, aucune valeur-objet possible n'est falsey, et donc dans un paramètre 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]
3
ELLIOTTCABLE

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
2
JessyNinja

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

2
Kanan Farzali
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.

1
Jitendra virani

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, 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]
*/
1
Joe Pineda

Une autre façon de le faire consiste à tirer parti de la propriété length du tableau: regroupez les éléments non nuls situés à gauche du tableau, puis réduisez la longueur. Il s’agit d’un algorithme sur place (ne pas allouer de mémoire, ce qui est dommage pour le ramasse-miettes) et il présente un très bon comportement au mieux/moyen/pire des 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 une connexion en chaîne: 

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 } ) ;
1
GameAlchemist
foo = [0, 1, 2, "", , false, 3, "four", null]

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

résultats

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

'Abuser' de la boucle for ... in (object-member) . => 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);
1
michael.zech

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));
            });
        };
1
Sandeep M

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

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

Le meilleur moyen de supprimer les éléments vides consiste à utiliser Array.prototype.filter() , comme déjà mentionné dans d'autres réponses.

Malheureusement, Array.prototype.filter() n'est pas supporté par IE <9. Si vous devez toujours prendre en charge IE8 ou une version encore plus ancienne d'IE, vous pouvez utiliser le fichier polyfill suivant pour prendre en charge Array.prototype.filter() dans 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;
  };
}
0
John Slegers

c'est ma solution pour les champs vides propres.

Commencer à partir de l'objet taxes: obtenir uniquement l'attribut avail (avec la carte), filtrer les champs vides (avec le filtre), analyser les résultats en entier (avec la carte).

fees.map( ( e ) => e.avail ).filter( v => v!== '').map( i => parseInt( i ) );
0
Andrea Perdicchia

Si quelqu'un cherche à nettoyer tout le tableau ou l'objet, cela pourrait 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);

Sortie:

Supprime tout ce qui est null, undefined, "", " ", empty object ou empty array

jsfiddle ici

0
Puni

Un autre moyen:

function filter_array(test_array) {
    var index = -1,
        arr_length = test_array ? test_array.length : 0,
        resIndex = -1,
        result = [];

    while (++index < arr_length) {
        var value = test_array[index];

        if (value) {
            result[++resIndex] = value;
        }
    }

    return result;
}
console.log(filter_array([NaN, 0, 15, false, -22, '',undefined, 47, null]));
0
stalinrajindian

utilisez le filtre pour supprimer la chaîne vide dans le tableau.

var s = [ '1,201,karthikeyan,K201,HELPER,[email protected],8248606269,7/14/2017,45680,TN-KAR24,8,800,1000,200,300,Karthikeyan,11/24/2017,Karthikeyan,11/24/2017,AVAILABLE\r',
  '' ]
var newArr = s.filter(function(entry) { return entry.trim() != ''; })

console.log(newArr); 

0
KARTHIKEYAN.A

Celui-ci ne supprimera que les valeurs vides et non celles de Falsey, ce qui me semble plus souhaitable.

Il existe une option pour supprimer également les valeurs nulles.

Cette méthode devrait être beaucoup plus rapide que d'utiliser l'épissure.

    function cleanArray(a, removeNull) {
        var i, l, temp = [];
        l = a.length;
        if (removeNull) {
            for (i = 0; i < l; i++) {
                if (a[i] !== undefined && a[i] !== null) {
                    temp.Push(a[i]);
                }
            }
        } else {
            for (i = 0; i < l; i++) {
                if (a[i] !== undefined) {
                    temp.Push(a[i]);
                }
            }
        }
        a.length = 0;
        l = temp.length;
        for (i = 0; i < l; i++) {
            a[i] = temp[i];
        }
        temp.length = 0;
        return a;
    }
    var myArray = [1, 2, , 3, , 3, , , 0, , null, false, , NaN, '', 4, , 4, , 5, , 6, , , , ];
    cleanArray(myArray);
    myArray;
0
Trevor