Entfernen Sie leere Elemente aus einem Array in Javascript


1145

Wie entferne ich leere Elemente aus einem Array in JavaScript?

Gibt es einen einfachen Weg oder muss ich ihn durchlaufen und manuell entfernen?


14
Es wäre hilfreich, wenn Ihre Frage genau angegeben hätte, was Sie unter "leeren Elementen" verstehen, da die meisten Antworten hier dies falsch interpretieren (IMHO), um "falsey" -Elemente zu bedeuten. NB: Es gibt einen Unterschied zwischen dem, was Sie bekommen var a = [,,]und var a = [undefined, undefined]. Ersteres ist wirklich leer, aber letzteres hat tatsächlich zwei Schlüssel, aber mit undefinedWerten.
Alnitak

Antworten:


1065

EDIT: Diese Frage wurde vor fast neun Jahren beantwortet, als es in der nicht viele nützliche eingebaute Methoden gab Array.prototype.

Nun würde ich Ihnen sicherlich empfehlen, die filterMethode zu verwenden.

Beachten Sie, dass diese Methode Ihnen ein neues Array mit den Elementen zurückgibt, die die Kriterien der von Ihnen bereitgestellten Rückruffunktion erfüllen.

Zum Beispiel, wenn Sie nulloder undefinedWerte entfernen möchten :

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

Dies hängt davon ab, was Sie als "leer" betrachten. Wenn Sie sich beispielsweise mit Zeichenfolgen befassen, werden mit der obigen Funktion keine Elemente entfernt, die eine leere Zeichenfolge sind.

Ein typisches Muster , dass ich oft gebraucht wird Elemente zu entfernen, die falsy , die einen leeren String enthalten "", 0, NaN, null, undefined, und false.

Sie können an die filterMethode, die BooleanKonstruktorfunktion, übergeben oder dasselbe Element in der Filterkriterienfunktion zurückgeben, zum Beispiel:

var filtered = array.filter(Boolean);

Oder

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

In beiden filterFällen funktioniert dies, da die Methode im ersten Fall den BooleanKonstruktor als Funktion aufruft und den Wert konvertiert. Im zweiten Fall wandelt die filterMethode den Rückgabewert des Rückrufs intern implizit in um Boolean.

Wenn Sie mit spärlichen Arrays arbeiten und versuchen, die "Löcher" zu beseitigen, können Sie die filterMethode verwenden, die einen Rückruf übergibt, der true zurückgibt, zum Beispiel:

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

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

Alte Antwort: Tu das nicht!

Ich verwende diese Methode, um den nativen Array-Prototyp zu erweitern:

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

Oder Sie können die vorhandenen Elemente einfach in ein anderes Array verschieben:

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

110
WARNUNG: Mit der zweiten Option werden alle Elemente aus einem Array entfernt, die als "falsch" eingestuft werden, dh die Werte false, 0, null und undefined. Dieses Array würde am Ende überhaupt nichts enthalten: [null ,,, 0 ,, 0,0,0, false, null, 0], obwohl ich möglicherweise die Elemente mit den Werten 0 haben möchte, wie in diesem Array: [ 1,0,1,0,0,1]
Jason Bunting

5
Mir ist klar, dass ich deshalb nur von der zweiten Option gesprochen habe. Der erste ist so eng gefasst, dass ich zögern würde, ihn in den Prototyp des Arrays aufzunehmen. Siehe Alnitaks Antwort auf dieser Seite für etwas, das idealer wäre. Ihre erlaubt natürlich eine Verkettung.
Jason Bunting

1
Ihre erste Lösung ist wirklich nett, wenn Sie keinen Zugriff auf die "Filter" -Methode haben. Sonst glaube ich, dass Alnitaks Antwort besser ist.
Joe Pineda

2
@AlfaTek - Mit Ausnahme der neuesten Browser bietet # 2 die beste Leistung, da Arrays in JS keine wirklichen Arrays sind. Der spliceAnruf ist in älteren Browsern sehr teuer, da alle Array-Schlüssel neu nummeriert werden müssen, um die Lücke zu schließen.
Alnitak

1
@David nein, in modernem Code sollten Sie die Verwendung sicher erweitern , um die neue Funktion zu einer nicht aufzählbaren Eigenschaft zu machen, und dann den Leistungseinbruch vermeiden, der durch das Einfügen jeder Schleife verursacht wird. Array.prototypeObject.defineProperty.hasOwnProperty
Alnitak

1381

Einfache Wege:

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]

oder - (nur für einzelne Array-Elemente vom Typ "Text")

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

oder - Klassischer Weg: einfache Iteration

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]


über 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 - nur ein weiterer schneller und cooler Weg (mit 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]

Leere Werte entfernen

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

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

34
Die früheste IE-Unterstützung für Filter ist der IE9-Standardmodus.
Yincrash

14
für reines Javascript sollte es seinarr = arr.filter(function(n){return n; });
ilumin

19
foo.join("").split("")scheint nur zu funktionieren, wenn die Zeichenfolgen einzelne Zeichen sind
Atav32

9
Ihr reiner JavaScript-Code hat einen Fehler. Wenn das Array einen Wert mit "0" enthält, wird der Wert herausgefiltert, da "0" falsch ist. Was Sie wollen, ist: arr.filter (Funktion (n) {return (n! == undefined && n! == null);});
John Kurlak

5
ES6 kann es noch einfacher machen arr.filter(e=>e)und dies kann durch Karte, Verkleinerung usw. verkettet werden.
Sheepy

241

Wenn Sie ALLE leeren Werte entfernen müssen ("", null, undefined und 0):

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

So entfernen Sie leere Werte und Zeilenumbrüche:

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

Beispiel:

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

Rückkehr:

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

UPDATE (basierend auf Alnitaks Kommentar)

In einigen Situationen möchten Sie möglicherweise "0" im Array behalten und alles andere (null, undefiniert und "") entfernen. Dies ist eine Möglichkeit:

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

Rückkehr:

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

Ja, das ist schön, denn es entfernt auch "".
Vladimirs

3
Die Testfunktion könnte etwas expliziter sein:function(e){return !!e}
Koen.

4
@Koen Bitte beachten Sie, dass !!eNaN (im Gegensatz zu 0) enthalten ist e, wo nicht (wie 0).
Sheepy

Beantwortet die gestellte Frage nicht wirklich.
Alnitak

2
ODER Verwendung var myarr=[1, 2,, 3,, 3,undefined,,"",,0, 4,, 4,, 5,, 6,,,,].filter(Boolean);entfernt undefinierte "" und 0
Mark Schultheiss

134

Einfach ein Liner:

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

oder mit underscorejs.org :

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

1
Das ist wirklich cool - ich habe allerdings eine neue Frage: Es sieht so aus, als würden Sie einen Klassennamen als Funktionsaufruf verwenden - ist das Typografie? Ich habe das noch nie gesehen und bin mir nicht sicher, warum das Übergeben Booleanals Funktion funktioniert ...
Andrew

8
Wenn Sie Booleanals Funktion behandeln, wird einfach zurückgegeben trueoder falseob der Wert wirklich / falsch ist.
andlrc

8
Sie behandeln Boolesche Werte nicht als Funktion. es ist eine Funktion. (Eine völlig normale Funktion, außer dass sie nativ implementiert ist.) Jemand muss ein wenig über das JavaScript-Objektmodell recherchieren. ;)
ELLIOTTCABLE

@ELLIOTTCABLE Ich lasse das hier (true).constructor === Boolean. Und dann sagen Sie mir, ob wir dies mit anderen Build-Ins in JS tun können. ;)) (natürlich ausgeschlossen die anderen 5 eingebauten Konstruktoren. (String, Array, Objekt, Funktion, Nummer))
andlrc

1
Wird beide fehlschlagen, wenn es Wert 0 im Array gibt
Sai Ram

129

Wenn Sie Javascript 1.6 oder höher haben, können Sie Array.filtereine einfache return trueRückruffunktion verwenden, z.

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

da .filterfehlende Elemente im ursprünglichen Array automatisch übersprungen werden.

Die oben verlinkte MDN-Seite enthält auch eine nette Version zur Fehlerprüfung filter, die in JavaScript-Interpreten verwendet werden kann, die die offizielle Version nicht unterstützen.

Beachten Sie, dass dadurch weder nullEinträge noch Einträge mit einem expliziten undefinedWert entfernt werden, das OP jedoch speziell "fehlende" Einträge angefordert hat.


Du hast recht! Es kann so einfach sein (und funktioniert!): Test3 = [1,2 ,, 3 ,, 3 ,,,, 7 ,,, 7 ,,, 0 ,,, 4 ,, 4 ,, 5 ,, 6 ,, undefiniert ,, null ,,]; printp ("Verwenden der nativen Filterung des Arrays:", test3.filter (Funktion (Wert) {return (Wert == undefiniert)? 0: 1;}));
Joe Pineda

3
+1 Wie Alnitak sagte, haben sie den Code, der verwendet werden kann, wenn js 1.6 nicht verfügbar ist
Sameer Alibhai

3
@katsh Ich habe geklärt - der Code oben tut Arbeit Einträge zu entfernen , für die kein Wert überhaupt existiert, die (ich habe später) gelernt auf den Fall eines Schlüssels semantisch verschieden ist , die vorhanden ist, aber die hat undefinedals gegebenen Wert.
Alnitak

4
Um undefinierte oder Null-Einträge zu entfernen, nehmen Sie einfach eine kleine Änderung vor ... arr = arr.filter (function (v) {return v;});
Alan CN

4
@ AlanCN du hast meinen Standpunkt völlig verfehlt. Das OP bat darum, fehlende Einträge zu entfernen , während der Großteil der Antworten hier (fälschlicherweise) alle "Falsey" -Einträge entfernt.
Alnitak

65

Zum Entfernen von Löchern sollten Sie verwenden

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

Zum Entfernen von Loch- und Falschwerten (null, undefiniert, 0, -0, NaN, "", false, document.all):

arr.filter(x => x)

Zum Entfernen von Loch, Null und undefiniert:

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]


3
Dies sollte in der Antwort ganz oben stehen. Können Sie erweitern, was Sie unter Löchern verstehen?
Samayo

2
@ Samayo Löcher sind ungefüllte Array-Elemente, dh[, ,]
Jimmy Obonyo Abor

Durch die Verwendung von arr.filter(x => x)JS wird geprüft, ob x wahr oder falsch ist, dh if (x), der neuen Liste wird nur der Wahrheitswert zugewiesen.
KuanYu Chu

56

Der saubere Weg, es zu tun.

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

5
Leere Elemente sind undefined; Dadurch werden grundsätzlich alle falschen Werte entfernt.
Pimvdb

33

Einfaches ES6

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

1
Das funktioniert nicht : [1, 'two', null, undefined, , NaN, false, true, 0].filter(v => v).
Reißverschluss

22

Mit Unterstrich / Lodash:

Allgemeiner Anwendungsfall:

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

Mit Leergut:

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

Siehe lodash Dokumentation für ohne .


Das Problem mit #compact ist, dass alle falschen Werte entfernt werden. Wenn Ihr Array also 0 Werte enthält, werden diese ebenfalls entfernt.
Samuel Brandão

21

Angenommen ES6, das Array befindet sich in der Methode für gerechte und neuere Versionen:

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

Einfacher Weg:

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

16

Wenn die Verwendung einer Bibliothek eine Option ist, von der ich weiß, dass underscore.js eine Funktion namens compact () http://documentcloud.github.com/underscore/ hat, hat es auch einige andere nützliche Funktionen in Bezug auf Arrays und Sammlungen.

Hier ist ein Auszug aus ihrer Dokumentation:

_.compact (Array)

Gibt eine Kopie des Arrays zurück, bei der alle falschen Werte entfernt wurden. In JavaScript sind false, null, 0, "", undefined und NaN alle falsch.

kompakt ([0, 1, falsch, 2, '', 3]);

=> [1, 2, 3]


Es entfernt auch nicht leere Elemente definierte Elemente wie 0.
Timothy Gu

15

@ Alnitak

Tatsächlich funktioniert Array.filter in allen Browsern, wenn Sie zusätzlichen Code hinzufügen. Siehe unten.

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

Dies ist der Code, den Sie für den IE hinzufügen müssen, aber Filter und funktionale Programmierung sind imo wert.

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

Dies sollte die akzeptierte Antwort sein, da sie sofort funktioniert. Vielen Dank.
Tony

@ Tony nein, sollte es nicht, da ein Element mit einer leeren Zeichenfolge nicht dasselbe ist wie ein "leeres Element", wobei letzteres das ist, wonach das OP gefragt hat.
Alnitak

14

Da es sonst niemand erwähnt hat und die meisten Leute Unterstriche in ihr Projekt aufgenommen haben, können Sie es auch verwenden _.without(array, *values);.

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


8

Möglicherweise fällt es Ihnen leichter, eine Schleife über Ihr Array zu erstellen und aus den Elementen, die Sie aus dem Array entfernen möchten, ein neues Array zu erstellen, als wie vorgeschlagen zu schleifen und zu verbinden, da Sie die Länge des Arrays während der Schleife ändern über kann Probleme verursachen.

Sie könnten so etwas tun:

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

Eigentlich ist hier eine allgemeinere Lösung:

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]

Sie haben die Idee - Sie könnten dann andere Arten von Filterfunktionen haben. Wahrscheinlich mehr als du brauchst, aber ich fühlte mich großzügig ...;)


7

Was ist damit (ES6): So entfernen Sie den Falsy-Wert aus einem 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"]

6

Sie sollten Filter verwenden, um ein Array ohne leere Elemente zu erhalten. Beispiel auf ES6

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

3

Ich füge einfach meine Stimme zu den oben „nennen ES5 ist Array..filter()mit einem globalen Konstruktor“ Golf-Hack, aber ich schlage vor , mit Objectstatt String, Booleanoder Numberwie oben vorgeschlagen.

Insbesondere werden ES5- Elemente filter()bereits nicht für undefinedElemente innerhalb des Arrays ausgelöst . so eine Funktion , die allgemein zurückkehrt true, die zurückgibt alle Elemente filter()Hits, wird zwangsläufig nur nicht zurückkehren undefinedElemente:

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

Das Ausschreiben ...(function(){return true;})ist jedoch länger als das Schreiben ...(Object). und der Rückgabewert des ObjectKonstruktors ist unter keinen Umständen eine Art Objekt. Im Gegensatz zu den oben vorgeschlagenen primitiven Boxkonstruktoren ist kein möglicher Objektwert falsey und daher in einer booleschen Umgebung Objecteine Abkürzung für 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]

1
ACHTUNG: Filter (String) und Filter (Objekt) filtern keine Nullen oder Zahlen heraus. Da ein Konstruktor auch eine Funktion ist, können Sie String an Filter übergeben, dh someArray.filter(String);tatsächlich äquivalent zu someArray.filter(function(x){ return String(x); });. Wenn Sie alle falschen Werte entfernen möchten someArray.filter(Boolean);, werden 0, -0, NaN, false, '', null und undefined entfernt.
Robocat

1
Gute Antwort, obwohl ich mich über den Leistungsaufwand beim Aufrufen des ObjectKonstruktors im Gegensatz zur return trueMethode wundere . @robocat Das OP hat darum gebeten, leere Elemente zu entfernen, keine Nullen.
Alnitak

Ich bevorzuge die kürzeste und klarste Lösung, außer in engen Schleifen. Persönliche Vorlieben, nehme ich an. (=
ELLIOTTCABLE

3

Bei Verwendung der Antwort mit der höchsten Bewertung oben, dem ersten Beispiel, wurden einzelne Zeichen für Zeichenfolgenlängen größer als 1 angezeigt. Nachfolgend ist meine Lösung für dieses Problem aufgeführt.

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

Anstatt nicht zurückzukehren, wenn es nicht definiert ist, kehren wir zurück, wenn die Länge größer als 0 ist. Ich hoffe, das hilft jemandem da draußen.

Kehrt zurück

["some string yay", "Other string yay"]

+1, da dies sehr praktisch ist und genau das ist, was ich normalerweise für die Arbeit mit String-Arrays benötige. Beachten Sie jedoch, dass dadurch Zahlen entfernt werden (wenn sie nicht in String-Form vorliegen), da sie keine Länge haben. ["", "some string yay", "", "", 123, "Other string yay"].filter(function(n){ return n.length > 0}) //gives your same result removing 123Ersetzen Sie diese Funktion. .. mit String lässt ironischerweise Zahlen in, würde aber in Ihrem angegebenen Array das gleiche Ergebnis liefern.
aamarks

3
var data = [null, 1,2,3];
var r = data.filter(function(i){ return i != null; })

console.log(r) 

[1,2,3]


Dies ist der offensichtlich richtige Weg und sollte ganz oben stehen!
Martin Andersson

2

Was ist damit:

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

6
join() === join(','):)
pimvdb

1

Dies funktioniert, ich habe es in AppJet getestet (Sie können den Code kopieren und in die IDE einfügen und auf " Neu laden" klicken, um zu sehen, dass es funktioniert. Sie müssen kein Konto erstellen.)

/* 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
Dies scheint nur "aus Versehen" zu funktionieren, da das Aufzählen der Schlüssel über for ... intatsächlich das Überspringen fehlender Elemente verursacht. Der Test für undefineddient nur dazu, reale Elemente zu entfernen, die explizit auf diesen Wert festgelegt sind.
Alnitak

1

Eine andere Möglichkeit besteht darin, die Eigenschaft length des Arrays zu nutzen: Packen Sie die Nicht-Null-Elemente links vom Array und reduzieren Sie dann die Länge. Es handelt sich um einen In-Place-Algorithmus, der keinen Speicher zuweist, was für den Garbage Collector zu schlecht ist. Er weist ein sehr gutes Best- / Average- / Worst-Case-Verhalten auf.

Diese Lösung ist im Vergleich zu anderen hier in Chrome 2- bis 50-mal schneller und in Firefox 5- bis 50-mal schneller, wie Sie hier sehen können: http://jsperf.com/remove-null-items-from-array

Der folgende Code fügt dem Array die nicht aufzählbare Methode 'removeNull' hinzu, die für die Verkettung 'this' zurückgibt:

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

Schöne Antwort, obwohl es gut wäre, einige Testfälle zu sehen, um sie in Aktion zu zeigen!
Alnitak

2
Diese Antwort ist sehr faszinierend, erinnert mich aber irgendwie an einen Computer, der 1945 gebaut wurde, als ich ein Smartphone hatte : arr.filter(e => e).
agm1984

@ agm1984 Ihr Smartphone ist nicht schlau
Hernán Eche vor

Das kann von Ihrer Definition von smart- wie dem Verb - abhängen , um einen scharfen stechenden Schmerz zu verursachen. Dies ist aufgrund der körperlichen Schmerzen relevant, wenn ich mein Telefon aufgrund Ihres Kommentars mit Waffen bewaffne.
agm1984 vor

1
foo = [0, 1, 2, "", , false, 3, "four", null]

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

kehrt zurück

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

1

'Missbrauch' der for ... in (Objektelement-) Schleife. => Im Rumpf der Schleife erscheinen nur wahrheitsgemäße Werte.

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

Der Code ist richtig, der Kommentar ist falsch. Durch die Verwendung werden for ... indie undefinierten Schlüssel aus dem Array entfernt, aber Sie haben hier eigentlich keinen Code, um ansonsten nur "wahrheitsgemäße" Werte zu akzeptieren
Alnitak,

1

Dies könnte Ihnen helfen: 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
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);

Ausgabe:

Ich arbeite an NodeJS

Das leere Element wird aus dem Array entfernt und ein anderes Element angezeigt.


Ausgabe: 'Ich arbeite an NodeJS'. Das leere Element wird aus dem Array entfernt und ein anderes Element angezeigt.
Jitendra Virani

Ich habe deine Antwort verbessert. Bitte versuchen Sie eine einfache, klare und lesbare Antwort zu geben;)
GGO

1

Alle leeren Elemente entfernen

Wenn ein Array neben anderen leeren Elementen leere Objekte, Arrays und Strings enthält, können wir sie entfernen mit:

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

Einfaches Komprimieren (Entfernen leerer Elemente aus einem Array)

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

Mit einfachem Javascript ->

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)


0

Herausfiltern ungültiger Einträge mit einem regulären Ausdruck

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

Funktioniert das? es zeigt einen Fehler TypeError: [Objekt RegExp] ist keine Funktion
FreeLightman

0

Der beste Weg, leere Elemente zu entfernen, ist die Verwendung Array.prototype.filter(), wie bereits in anderen Antworten erwähnt.

Wird leider Array.prototype.filter()nicht von IE <9 unterstützt. Wenn Sie IE8 oder eine noch ältere Version von IE weiterhin unterstützen müssen, können Sie die folgende Polyfüllung verwenden , um Unterstützung für Array.prototype.filter()diese Browser hinzuzufügen :

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;
  };
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.