Wie entferne ich leere Elemente aus einem Array in JavaScript?
Gibt es einen einfachen Weg oder muss ich ihn durchlaufen und manuell entfernen?
Wie entferne ich leere Elemente aus einem Array in JavaScript?
Gibt es einen einfachen Weg oder muss ich ihn durchlaufen und manuell entfernen?
Antworten:
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 filter
Methode 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 null
oder undefined
Werte 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 filter
Methode, die Boolean
Konstruktorfunktion, ü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 filter
Fällen funktioniert dies, da die Methode im ersten Fall den Boolean
Konstruktor als Funktion aufruft und den Wert konvertiert. Im zweiten Fall wandelt die filter
Methode 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 filter
Methode 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,,,,]);
splice
Anruf ist in älteren Browsern sehr teuer, da alle Array-Schlüssel neu nummeriert werden müssen, um die Lücke zu schließen.
Array.prototype
Object.defineProperty
.hasOwnProperty
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]
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("")
scheint nur zu funktionieren, wenn die Zeichenfolgen einzelne Zeichen sind
arr.filter(e=>e)
und dies kann durch Karte, Verkleinerung usw. verkettet werden.
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, " "]
function(e){return !!e}
!!e
NaN (im Gegensatz zu 0) enthalten ist e
, wo nicht (wie 0).
var myarr=[1, 2,, 3,, 3,undefined,,"",,0, 4,, 4,, 5,, 6,,,,].filter(Boolean);
entfernt undefinierte "" und 0
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]
Boolean
als Funktion funktioniert ...
Boolean
als Funktion behandeln, wird einfach zurückgegeben true
oder false
ob der Wert wirklich / falsch ist.
(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))
Wenn Sie Javascript 1.6 oder höher haben, können Sie Array.filter
eine einfache return true
Rückruffunktion verwenden, z.
arr = arr.filter(function() { return true; });
da .filter
fehlende 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 null
Einträge noch Einträge mit einem expliziten undefined
Wert entfernt werden, das OP jedoch speziell "fehlende" Einträge angefordert hat.
undefined
als gegebenen Wert.
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]
[, ,]
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.
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"]
undefined
; Dadurch werden grundsätzlich alle falschen Werte entfernt.
Einfaches ES6
['a','b','',,,'w','b'].filter(v => v);
[1, 'two', null, undefined, , NaN, false, true, 0].filter(v => v)
.
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 .
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]
@ 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;
};
}
let newArr = arr.filter(e => e);
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 ...;)
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);
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 Object
statt String
, Boolean
oder Number
wie oben vorgeschlagen.
Insbesondere werden ES5- Elemente filter()
bereits nicht für undefined
Elemente 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 undefined
Elemente:
> [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 Object
Konstruktors 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 Object
eine 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]
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.
Object
Konstruktors im Gegensatz zur return true
Methode wundere . @robocat Das OP hat darum gebeten, leere Elemente zu entfernen, keine Nullen.
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"]
["", "some string yay", "", "", 123, "Other string yay"].filter(function(n){ return n.length > 0}) //gives your same result removing 123
Ersetzen Sie diese Funktion. .. mit String lässt ironischerweise Zahlen in, würde aber in Ihrem angegebenen Array das gleiche Ergebnis liefern.
var data = [null, 1,2,3];
var r = data.filter(function(i){ return i != null; })
console.log(r)
[1,2,3]
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
join() === join(',')
:)
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]
*/
for ... in
tatsächlich das Überspringen fehlender Elemente verursacht. Der Test für undefined
dient nur dazu, reale Elemente zu entfernen, die explizit auf diesen Wert festgelegt sind.
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 } ) ;
arr.filter(e => e)
.
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.
'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);
for ... in
die undefinierten Schlüssel aus dem Array entfernt, aber Sie haben hier eigentlich keinen Code, um ansonsten nur "wahrheitsgemäße" Werte zu akzeptieren
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));
});
};
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.
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))
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)
Herausfiltern ungültiger Einträge mit einem regulären Ausdruck
array = array.filter(/\w/);
filter + regexp
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;
};
}
var a = [,,]
undvar a = [undefined, undefined]
. Ersteres ist wirklich leer, aber letzteres hat tatsächlich zwei Schlüssel, aber mitundefined
Werten.