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?
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?
Réponses:
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 filter
mé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 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 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
, undefined
et false
.
Vous pouvez passer à la filter
méthode, à la Boolean
fonction 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 filter
méthode dans le premier cas, appelle le Boolean
constructeur en tant que fonction, convertissant la valeur et dans le second cas, la filter
mé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 filter
mé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,,,,]);
splice
appel est vraiment cher sur les anciens navigateurs car ils doivent renuméroter toutes les clés du tableau pour combler l'écart.
Array.prototype
utilisant Object.defineProperty
pour faire de la nouvelle fonction une propriété non énumérable , puis éviter les performances affectées par l'insertion .hasOwnProperty
de chaque boucle.
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]
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]
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]
['foo', '',,,'',,null, ' ', 3, true, [], [1], {}, undefined, ()=>{}].filter(String)
// ["foo", null, " ", 3, true, [1], Object {}, undefined, ()=>{}]
arr = arr.filter(function(n){return n; });
foo.join("").split("")
ne semble fonctionner que si les chaînes sont des caractères uniques
arr.filter(e=>e)
et cela peut être enchaîné par carte, réduire, etc.
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, " "]
function(e){return !!e}
!!e
cela inclura NaN (contrairement à 0) où e
non (comme 0).
var myarr=[1, 2,, 3,, 3,undefined,,"",,0, 4,, 4,, 5,, 6,,,,].filter(Boolean);
supprime undefined, "" et 0
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]
Boolean
fonctionne en fonction ...
Boolean
comme une fonction, elle retournera simplement true
ou false
si la valeur est vraiment / fausse.
(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))
Si vous avez Javascript 1.6 ou une version ultérieure, vous pouvez utiliser Array.filter
une return true
fonction de rappel triviale , par exemple:
arr = arr.filter(function() { return true; });
car .filter
saute 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 filter
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 null
entrées ni les entrées avec une undefined
valeur explicite , mais l'OP a spécifiquement demandé des entrées "manquantes".
undefined
pour valeur donnée.
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]
[, ,]
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.
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"]
undefined
; cela supprime essentiellement toutes les valeurs de falsification.
ES6 simple
['a','b','',,,'w','b'].filter(v => v);
[1, 'two', null, undefined, , NaN, false, true, 0].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 des vides:
_.without(['foo', 'bar', '', 'baz', '', '', 'foobar'], '');
--> ["foo", "bar", "baz", "foobar"]
Voir la documentation de lodash sans .
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]
@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;
};
}
let newArr = arr.filter(e => e);
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 ...;)
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);
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 Object
lieu de String
, Boolean
ou Number
comme 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 Object
constructeur 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, 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]
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.
Object
constructeur par opposition à la return true
méthode. @robocat l'OP a demandé que les éléments vides soient supprimés, pas les valeurs nulles.
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"]
["", "some string yay", "", "", 123, "Other string yay"].filter(function(n){ return n.length > 0}) //gives your same result removing 123
Remplacer cette fonction. .. avec String, ironiquement, laisse des nombres mais donnerait le même résultat dans votre tableau donné.
var data = [null, 1,2,3];
var r = data.filter(function(i){ return i != null; })
console.log(r)
[1,2,3]
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
join() === join(',')
:)
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]
*/
for ... in
qui provoque en fait le saut des éléments manquants. Le test de undefined
sert uniquement à supprimer les éléments réels qui sont explicitement définis sur cette valeur.
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 } ) ;
arr.filter(e => e)
.
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.
'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);
for ... in
est 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"
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));
});
};
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.
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))
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)
Filtrer les entrées non valides avec une expression régulière
array = array.filter(/\w/);
filter + regexp
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;
};
}
var a = [,,]
etvar a = [undefined, undefined]
. Le premier est vraiment vide, mais le second a en fait deux clés, mais avec desundefined
valeurs.