Domanda

Come rimuovo gli elementi vuoti da un array in JavaScript?

Esiste un modo semplice o devo scorrere e rimuoverlo manualmente?

È stato utile?

Soluzione

MODIFICA: a questa domanda è stata data risposta quasi 9 anni fa, quando non vi erano metodi incorporati molto utili in Array.prototype.

Ora, certamente ti consiglierei di usare il metodo filter.

Tieni presente che questo metodo ti restituirà un nuovo array con gli elementi che superano i criteri della funzione di callback che gli fornisci, ad esempio se vuoi rimuovere null o undefined valori:

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

Dipenderà da ciò che consideri " vuoto " ;, ad esempio se hai a che fare con stringhe, la funzione sopra non rimuoverà elementi che sono una stringa vuota.

Un modello comune che vedo spesso usato è quello di rimuovere elementi che sono falsi , che includono una stringa vuota "", 0, NaN, false, Boolean e <=>.

Puoi semplicemente passare al metodo <=>, alla funzione <=> costruttore o semplicemente restituire lo stesso elemento nella funzione dei criteri di filtro, ad esempio:

var filtered = array.filter(Boolean);

o

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

In entrambi i modi funziona perché il metodo <=> nel primo caso, chiama il costruttore <=> come funzione, convertendo il valore e nel secondo caso, il metodo <=> converte internamente il valore restituito di la richiamata implicitamente a <=>.

Se si lavora con array sparsi e si sta tentando di eliminare " fori " è possibile utilizzare semplicemente il metodo <=> passando un callback che restituisce true, ad esempio :

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

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

Vecchia risposta: non farlo!

Uso questo metodo, estendendo il prototipo dell'array nativo:

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

Oppure puoi semplicemente inserire gli elementi esistenti in un altro array:

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

Altri suggerimenti

Modi semplici:

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]

oppure - (solo per elementi di array di tipo "text")

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

o - Modo classico: iterazione semplice

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]

tramite 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]

AGGIORNAMENTO - solo un altro modo veloce e interessante (usando 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]

Rimuovi valori vuoti

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

// ["foo", null, " ", 3, true, [1], Object {}, undefined, ()=>{}]

Se è necessario rimuovere TUTTI i valori vuoti (" " ;, null, non definito e 0):

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

Per rimuovere valori vuoti e interruzioni di riga:

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

Esempio:

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

Ritorno:

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

AGGIORNAMENTO (basato sul commento di Alnitak)

In alcune situazioni potresti voler mantenere " 0 " nell'array e rimuovere qualsiasi altra cosa (null, non definito e " "), questo è un modo:

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

Ritorno:

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

Semplicemente una linea:

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

o utilizzando underscorejs.org :

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

Se hai Javascript 1.6 o versioni successive puoi utilizzare Array.filter utilizzando una banale funzione di callback return true , ad esempio:

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

poiché .filter salta automaticamente gli elementi mancanti nell'array originale.

La pagina MDN collegata sopra contiene anche una bella versione per il controllo degli errori del filtro che può essere utilizzata negli interpreti JavaScript che non supportano la versione ufficiale.

Si noti che ciò non rimuoverà le voci null né le voci con un valore non definito esplicito, ma l'OP ha richiesto specificamente "manca". voci.

Per rimuovere i buchi, dovresti usare

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

Per rimuovere i valori hole, e, falsy (null, undefined, 0, -0, NaN, " " ;, false, document.all):

arr.filter(x => x)

Per rimuovere hole, null e, non definito:

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]

Il modo pulito per farlo.

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"]

ES6 semplice

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

Con Underscore / Lodash:

Caso d'uso generale:

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

Con vuoti:

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

Consulta la documentazione lodash per senza .

Solo ES6 e il metodo delle versioni più recenti, supponiamo che l'array sia sotto:

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

Modo semplice:

 const clearArray = arr.filter( i => i );

Se l'uso di una libreria è un'opzione, so che underscore.js ha una funzione chiamata compact () http: // documentcloud.github.com/underscore/ ha anche molte altre utili funzioni relative ad array e raccolte.

Ecco un estratto dalla loro documentazione:

  

_.compact (array)

     

Restituisce una copia dell'array con tutti i valori falsi rimossi. In JavaScript, false, null, 0, " " ;, undefined e NaN sono tutti falsi.

     

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

     

= > [1, 2, 3]

@Alnitak

In realtà Array.filter funziona su tutti i browser se aggiungi del codice aggiuntivo. Vedi sotto.

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"]  

Questo è il codice che devi aggiungere per IE, ma vale la pena applicare il filtro e la programmazione funzionale.

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

Dato che nessun altro lo ha menzionato e la maggior parte delle persone ha sottolineato il carattere di sottolineatura incluso nel loro progetto, è anche possibile utilizzare _.without (array, * valori); .

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

Potresti trovare più semplice passare in rassegna il tuo array e creare un nuovo array dagli elementi che desideri mantenere dall'array piuttosto che provare a eseguire il loop e il giunzione come è stato suggerito, dal momento che modificando la lunghezza dell'array mentre esso è in loop può introdurre problemi.

Potresti fare qualcosa del genere:

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

In realtà ecco una soluzione più generica:

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]

Hai avuto l'idea: potresti quindi avere altri tipi di funzioni di filtro. Probabilmente più del necessario, ma mi sentivo generoso ...;)

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

Che dire di questo (ES6): per rimuovere il valore Falsy da un array.

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"]

Dovresti usare il filtro per ottenere & nbsp; array senza elementi vuoti. Esempio su ES6

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

Sto semplicemente aggiungendo la mia voce al precedente & # 8220; chiama Array..filter () di ES5 con un costruttore globale & # 8221; golf-hack, ma suggerisco di usare Object invece di String , Boolean o Number come suggerito sopra.

In particolare, il filter () di ES5 non si attiva già per gli elementi non definiti all'interno dell'array; pertanto una funzione che restituisce universalmente true , che restituisce tutti elementi filter () , restituisce necessariamente solo <->> non definito elementi:

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

Tuttavia, scrivere ... (function () {return true;}) è più lungo della scrittura di ... (Object) ; e il valore di ritorno del costruttore Object sarà, in qualsiasi circostanza , una sorta di oggetto. A differenza dei costruttori di boxe primitivi suggeriti sopra, nessun valore-oggetto possibile è falso, e quindi in un'impostazione booleana, Object è una scorciatoia per la funzione () {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]

Quando ho usato la risposta più votata sopra, nel primo esempio, ho ricevuto caratteri individuali per lunghezze di stringa superiori a 1. Di seguito è la mia soluzione per questo problema.

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

Invece di non tornare se non definito, torniamo se la lunghezza è maggiore di 0. Spero che aiuti qualcuno là fuori.

Restituisce

["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]

Che dire:

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

Funziona, l'ho testato in AppJet (puoi copiare e incollare il codice sul suo IDE e premere " ; ricaricare " per vederlo funzionare, non è necessario creare un account)

/* 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]
*/

Un altro modo per farlo è sfruttare la proprietà length dell'array: impacchettare gli elementi non nulli sulla "sinistra" dell'array, quindi ridurre la lunghezza. È un algoritmo sul posto -non alloca la memoria, troppo male per il garbage collector-, e ha un ottimo comportamento migliore / medio / peggiore.

Questa soluzione, rispetto ad altre qui, è da 2 a 50 volte più veloce su Chrome e da 5 a 50 volte più veloce su Firefox, come potresti vedere qui: http://jsperf.com/remove-null-items-from-array

Il codice seguente aggiunge il metodo 'removeNull' non enumerabile all'array, che restituisce 'this' per il collegamento in cascata:

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

rendimenti

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

'Uso improprio' del ciclo for ... in (oggetto-membro).   = & Gt; Solo i valori di verità appaiono nel corpo del ciclo.

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

Questo potrebbe aiutarti: https://lodash.com/docs/4.17.4# rimuovere

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

Output:

  

Sto lavorando su nodejs

Rimuoverà l'elemento vuoto dall'array e visualizzerà altri elementi.

Filtraggio di voci non valide con un'espressione regolare

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

Il modo migliore per rimuovere elementi vuoti è usare Array.prototype.filter () , come già menzionato in altre risposte.

Sfortunatamente, Array.prototype.filter () non è supportato da IE < 9. Se hai ancora bisogno di supportare IE8 o una versione ancora più vecchia di IE, puoi usare il seguente polyfill per aggiungere il supporto per Array.prototype.filter () in questi browser:

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

Se qualcuno sta cercando di pulire l'intera matrice o oggetto, ciò potrebbe essere utile .

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

Output:

Rimuove tutto ciò che è null , undefined , " " , " " , oggetto vuoto o array vuoto

jsfiddle qui

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top