Javascript'teki bir diziden boş öğeleri kaldırma


1145

JavaScript'teki bir diziden boş öğeleri nasıl kaldırabilirim?

Basit bir yol var mı, yoksa bunun üzerinden geçip manuel olarak kaldırmam gerekiyor mu?


14
Sorunuzun "boş öğeler" ile tam olarak ne demek istediğinizi belirtmiş olması yararlı olacaktır, çünkü buradaki yanıtların çoğu bunu yanlış (IMHO) "falsey" öğeler olarak yorumlamaktadır. Not: ne için olsun arasında bir fark yoktur var a = [,,]ve var a = [undefined, undefined]. Birincisi gerçekten boş, ancak ikincisinin aslında iki anahtarı var, ancak undefineddeğerlerle.
Alnitak

Yanıtlar:


1065

EDIT: Bu soru neredeyse dokuz yıl önce içinde pek çok yararlı yerleşik yöntemler olmadığı zaman cevaplandı Array.prototype.

Şimdi, kesinlikle, filteryöntemi kullanmanızı tavsiye ederim .

Bu yöntemin, size sağladığınız geri arama işlevinin ölçütlerini geçen öğeleri içeren yeni bir dizi döndüreceğini unutmayın .

Örneğin, nullveya undefineddeğerleri kaldırmak istiyorsanız :

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

Örneğin "boş" olarak değerlendirdiğiniz şeylere bağlı olacaktır, örneğin dizelerle uğraşıyorsanız, yukarıdaki işlev boş bir dize olan öğeleri kaldırmaz.

Sık sık kullanılan gördüklerim tipik bir desen olan unsurları kaldırmaktır falsy boş bir dize içerir, "", 0, NaN, null, undefined, ve false.

filterYönteme, Booleanyapıcı işlevine geçebilir veya filtre ölçütü işlevinde aynı öğeyi döndürebilirsiniz, örneğin:

var filtered = array.filter(Boolean);

Veya

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

Her iki filterdurumda da, bu, ilk durumda yöntem Booleanyapıcıyı bir işlev olarak çağırır , değeri dönüştürür ve ikinci durumda filteryöntem, dahili olarak geri çağrının dönüş değerini dolaylı olarak döndürür Boolean.

Seyrek dizilerle çalışıyorsanız ve "deliklerden" kurtulmaya çalışıyorsanız, filtertrue değerini döndüren bir geri çağrı iletme yöntemini kullanabilirsiniz, örneğin:

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

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

Eski cevap: Bunu yapma!

Ben yerel Array prototip genişletme bu yöntemi kullanın:

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

Veya mevcut elemanları başka bir diziye itebilirsiniz:

// 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
UYARI: 2. seçenek, "falsy" olarak kabul edilen bir dizideki öğeleri, yani false, 0, null ve undefined değerlerini kaldırır. Bu dizi, hiçbir şeyle sonuçlanmayacaktı: [null ,,, 0,, ​​0,0,0, false, null, 0] bu dizideki gibi 0 değerine sahip öğeler isteyebilirim bile: [ 1,0,1,0,0,1]
Jason Bunting

5
Farkındayım - bu yüzden sadece ikinci seçenekten bahsettim. Birincisine gelince, kapsamı o kadar dar ki, onu Array'ın prototipinin bir parçası yapmaktan çekiniyorum. Daha ideal olacak bir şey için bu sayfadaki Alnitak'ın cevabına bakınız. Sizinki zincirleme izin veriyor, tabii ki.
Jason Bunting

1
"Filtre" yöntemine erişiminiz yoksa ilk çözümünüz gerçekten güzel. Yoksa Alnitak'ın cevabının daha iyi olduğuna inanıyorum.
Joe Pineda

2
@ Alfafa - en yeni tarayıcılar dışında # 2 en iyi performansa sahip olacak, çünkü JS'deki diziler gerçekten diziler değil. spliceÇağrıdır gerçekten onlar boşluğu kapatmak için dizi anahtarları tüm yeniden numaralandırmak çünkü eski tarayıcılarda pahalı.
Alnitak

1
Hiçbir modern kodda sen gerektiğini @ David güvenle uzatmak Array.prototypekullanarak Object.definePropertyyeni fonksiyonu bir hale getirmek için olmayan enumerable özelliğini ve sonra performans koyarak kaynaklanan hit önlemek .hasOwnPropertyher döngüde.
Alnitak

1381

Basit yollar:

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]

veya - (yalnızca "metin" türündeki tek dizi öğeleri için )

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

veya - Klasik yol: basit yineleme

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]


jQuery ile:

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]


GÜNCELLEME - sadece bir başka hızlı, havalı yol (ES6 kullanarak):

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]

Boş değerleri kaldır

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

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

34
Filtre için en erken IE desteği IE9 standart modudur.
19:19 yincrash

14
saf javascript için olmalıarr = arr.filter(function(n){return n; });
ilumin

19
foo.join("").split("")yalnızca dizeler tek karakter ise işe yarar
Atav32

9
Saf JavaScript kodunuzda bir hata var. Dizinin içinde "0" olan bir değer varsa, "0" yanlış olduğu için değer filtrelenir. İstediğiniz: arr.filter (function (n) {return (n! == undefined && n! == null);});
John Kurlak

5
ES6 daha da basit hale getirebilir arr.filter(e=>e)ve bu harita, azaltmak, vb. İle zincirlenebilir
Sheepy

241

TÜM boş değerleri ("", null, undefined ve 0) kaldırmanız gerekiyorsa:

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

Boş değerleri ve Satır sonlarını kaldırmak için:

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

Misal:

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

Dönüş:

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

GÜNCELLEME (Alnitak'ın yorumuna dayanarak)

Bazı durumlarda dizide "0" tutmak ve başka bir şeyi (null, undefined ve "") kaldırmak isteyebilirsiniz, bu bir yoludur:

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

Dönüş:

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

Evet bu çok güzel çünkü "" de kaldırılıyor.
Vladimirs

3
Test fonksiyonu biraz daha açık olabilir:function(e){return !!e}
Koen.

4
@Koen Unutmayın ki !!eNaN (0'dan farklı olarak) içermeyecektir e(0 gibi).
Sheepy

Sorulan soruya aslında cevap vermiyor.
Alnitak

2
VEYA kullanımı var myarr=[1, 2,, 3,, 3,undefined,,"",,0, 4,, 4,, 5,, 6,,,,].filter(Boolean);tanımsız, "" ve 0'ı kaldırır
Mark Schultheiss

134

Sadece bir astar:

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

veya underscorejs.org kullanarak :

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

1
Bu gerçekten harika - ama yeni bir sorum var: bir işlev adı olarak bir sınıf adı kullandığınız gibi görünüyor - bu daktilo mu? Bunu daha önce görmedim ve geçmenin neden Booleanbir işlev olarak çalıştığından emin değilim ...
Andrew

8
BooleanBir işlev olarak davranırsanız , değer gerçekten / falsy olup olmadığını döndürür trueveya falsedöndürür.
andlrc

8
Sen değilsin tedavi bir fonksiyonu olarak Boole; o ise bir fonksiyonu. (Doğal olarak uygulanması dışında tamamen normal bir işlevdir.) Birisinin JavaScript nesne modeli üzerinde biraz araştırma yapması gerekir. ;)
ELLIOTTCABLE

@ELLIOTTCABLE Bunu burada bırakacağım (true).constructor === Boolean. Ve sonra bunu JS'deki diğer yapılarla yapıp yapamayacağımızı söyle. ;)) (elbette diğer 5 yerleşik yapıcıyı hariç tuttu. (String, Array, Object, Function, Number))
andlrc

1
Dizide 0 değeri varsa her ikisi de başarısız olur
Sai Ram

129

Javascript 1.6 veya üst sürümüne sahipseniz, Array.filterönemsiz bir return truegeri arama işlevi kullanarak kullanabilirsiniz , örneğin:

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

çünkü .filterorijinal dizideki eksik öğeleri otomatik olarak atlar.

Yukarıda bağlantılı olan MDN sayfası filter, resmi sürümü desteklemeyen JavaScript yorumlayıcılarında kullanılabilecek güzel bir hata denetimi sürümü de içerir .

Bunun nullgirişleri veya açık bir undefineddeğeri olan girişleri kaldırmayacağını , ancak OP'nin özellikle "eksik" girişleri istediğini unutmayın.


Haklısın! Bu kadar basit olabilir (ve çalışıyor!): Test3 = [1,2,, 3,, 3 ,,,, 7 ,,, 7 ,,, 0 ,,, 4,, 4,, 5 ,, 6, tanımsız ,, boş ,,]; printp ("Dizinin yerel filtrelemesini kullanma:", test3.filter (function (value) {return (value == undefined)? 0: 1;}));
Joe Pineda

3
+1 Alnitak'ın dediği gibi, js
1.6'nın

3
@katsh ben açıklık ettik - Yukarıdaki kod yapar mevcut ancak bir anahtarın durumuna semantik farklı olan (I sonradan ettik) öğrenmiş, hiçbir değer mevcut olduğu girdileri kaldırmak için çalışmalarını olan undefinedonun verdiği değeri olarak.
Alnitak

4
Tanımlanmamış veya boş girişleri kaldırmak için küçük bir değişiklik yapın ... arr = arr.filter (function (v) {return v;});
Alan CN

4
@AlanCN benim fikrimi tamamen kaçırdın. OP eksik girişlerin kaldırılmasını istedi , cevapların büyük kısmı ise (yanlış) herhangi bir "falsey" girişini kaldırın.
Alnitak

65

Delikleri çıkarmak için şunu kullanmalısınız:

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

Delik ve falsy (null, undefined, 0, -0, NaN, "", false, document.all) değerlerini kaldırmak için:

arr.filter(x => x)

Boş, tanımsız ve tanımsız delikleri kaldırmak için:

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
Cevapta bu yüksek olmalı. Ne demek istediğini delik / delik ile genişletebilir misin?
samayo

2
@samayo delikleri doldurulmamış dizi öğeler yani[, ,]
Jimmy Obonyo Abor

arr.filter(x => x)JS kullanarak x'in doğruluk mu yoksa yanlış mı olduğunu kontrol eder, yani if (x)yeni listeye sadece doğruluk değeri atanır.
KuanYu Chu

56

Bunu yapmanın temiz yolu.

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
Boş elemanlar undefined; bu temelde tüm falsy değerlerini kaldırır.
pimvdb

33

Basit ES6

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

1
Bu işe yaramazsa: [1, 'two', null, undefined, , NaN, false, true, 0].filter(v => v).
fermuar

22

Alt Çizgi / Lodash ile:

Genel kullanım durumu:

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

Boşluklar ile:

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

Olmadan için lodash belgelerine bakın .


#Compact ile ilgili sorun, herhangi bir yanlış değeri kaldırmasıdır. Diziniz 0 değer içeriyorsa, bu değerler de kaldırılacaktır.
Samuel Brandão

21

Sadece ES6ve daha yeni sürümler yöntemi, dizi aşağıda olduğunu varsayalım:

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

Basit yol:

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

16

Bir kütüphane kullanmak bir seçenekse, underscore.js'nin compact () http://documentcloud.github.com/underscore/ adlı bir işlevi olduğunu ve ayrıca diziler ve koleksiyonlarla ilgili başka yararlı işlevleri de olduğunu biliyorum .

İşte belgelerinden bir alıntı:

_.compact (dizi)

Tüm falsy değerleri kaldırılmış olarak dizinin bir kopyasını döndürür. JavaScript'te false, null, 0, "", undefined ve NaN hepsi sahtedir.

_. kompakt ([0, 1, yanlış, 2 '', 3]);

=> [1, 2, 3]


Ayrıca, 0 gibi boş olmayan öğeleri de kaldırır.
Timothy Gu

15

@Alnitak

Aslında Array.filter fazladan kod eklerseniz tüm tarayıcılarda çalışır. Aşağıya bakınız.

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

Bu IE için eklemeniz gereken kod, ancak filtre ve Fonksiyonel programlama imo.

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

Bu kutudan çıktığı için kabul edilen cevap olmalıdır. Çok teşekkürler.
Tony

@Tony no, olmamalı, çünkü içinde boş bir dize olan bir eleman bir "boş eleman" ile aynı değildir, sonuncusu OP'nin istediği şeydir.
Alnitak

14

Başka hiç kimse bundan bahsetmediği ve çoğu insan projelerinde alt çizgi bulunduğundan da kullanabilirsiniz _.without(array, *values);.

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


8

Dizinizi döngü halindeyken dizinin uzunluğunu değiştirdiğinden, dizinizin üzerinde döngü oluşturmayı ve diziden saklamak istediğiniz öğelerden yeni bir dizi oluşturmayı önerebilirsiniz. fazla sorun getirebilir.

Bunun gibi bir şey yapabilirsiniz:

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

Aslında burada daha genel bir çözüm var:

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]

Fikir elde edersiniz - o zaman başka tür filtre fonksiyonlarına sahip olabilirsiniz. Muhtemelen ihtiyacınız olandan daha fazla, ama cömert hissediyordum ...;)


7

Peki ya (ES6): Bir diziden Falsy değerini kaldırmak için.

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

Boş öğeler olmadan dizi almak için filtre kullanmalısınız. ES6 örneği

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

3

Ben sadece “ES5 en çağrı yukarıda sesimi ekliyorum Array..filter()küresel kurucu ile” golf-hack ama kullanmanızı öneririz Objectyerine String, Booleanya Numberyukarıda önerildiği gibi.

Özellikle, ES5'ler dizideki öğeler filter()için zaten tetiklemiyor undefined; bu nedenle true, tüm öğelerin filter()isabetlerini döndüren evrensel olarak dönen bir işlev mutlaka yalnızca öğe olmayanları döndürür 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]

Ancak, yazmak yazmaktan ...(function(){return true;})daha uzundur ...(Object); ve dönüş değeri Objectyapıcısı altında olacak hiç bir şekilde , bir nesne bir çeşit. Yukarıda önerilen ilkel-boks yapıcılarının aksine, olası hiçbir nesne-değeri falsey değildir ve bu nedenle boolean bir ortamda Objectkısa bir eldir 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
DİKKAT: filter (String) ve filter (Object) null değerlerini veya sayıları filtrelemez. Bir kurucu da bir işlev someArray.filter(String);olduğu için filtreye yani yani eşdeğerdir someArray.filter(function(x){ return String(x); });. Tüm falsy değerlerini kaldırmak isterseniz someArray.filter(Boolean);0, -0, NaN, false, '', null ve undefined öğelerini kaldırmaya çalışır.
robocat

1
Güzel cevap, her ne Objectkadar return truemetodun aksine yapıcı çağırmak performans yükü merak ediyorum . @robocat OP boş elemanların değil boş elemanların kaldırılmasını istedi.
Alnitak

Sıkı döngüler dışında en kısa ve en net çözümü tercih ederim. Kişisel tercih, sanırım. (=
ELLIOTTCABLE

3

Yukarıdaki en yüksek oylanan cevap kullanırken, ilk örnek, ben 1'den büyük dize uzunlukları için tek tek karakterler alıyordu. Aşağıda bu sorun için benim çözüm aşağıdadır.

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

Tanımsızsa geri dönmemek yerine, uzunluk 0'dan büyükse geri dönüyoruz. Umarım orada birine yardımcı olur.

İadeler

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

Bu çok pratik ve tam olarak ben genellikle dize dizileri ile çalışmak için gereken +1, ama bu bir .lenghth olmadığı için bu numaraları (dize formunda değilse) kaldırır, yani ["", "some string yay", "", "", 123, "Other string yay"].filter(function(n){ return n.length > 0}) //gives your same result removing 123bu işlevi değiştirme unutmayın. .. iple, ironik olarak, sayıları bırakır ama verilen dizide aynı sonucu verir.
aamarks

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

console.log(r) 

[1,2,3]


Bunu yapmanın en doğru yolu budur ve en üstte olmalıdır!
Martin Andersson

2

Buna ne dersin:

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

Bu çalışır, AppJet'te test ettim (kodu IDE'ye kopyalayıp yapıştırabilir ve çalıştığını görmek için "yeniden yükle" ye basabilirsiniz, bir hesap oluşturmanıza gerek yoktur)

/* 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
Bu sadece "tesadüfen" çalışıyor gibi gözüküyor, çünkü for ... inaslında anahtarların numaralandırılması aslında eksik unsurların atlanmasına neden oluyor. Test, undefinedyalnızca açıkça bu değere ayarlanmış gerçek öğeleri kaldırmaya yarar.
Alnitak

1

Bunu yapmanın başka bir yolu da dizinin length özelliğinden yararlanmaktır: dizinin solundaki boş olmayan öğeleri paketleyip uzunluğu kısaltmaktır. Yerinde bir algoritmadır - bellek tahsis etmez, çöp toplayıcı için çok kötüdür - ve çok iyi en iyi / ortalama / en kötü durum davranışına sahiptir.

Bu çözüm, buradakilere kıyasla Chrome'da 2 ila 50 kat daha hızlı ve Firefox'ta 5 ila 50 kat daha hızlıdır: http://jsperf.com/remove-null-items-from-array

Aşağıdaki kod, array'a numaralandırılamayan 'removeNull' yöntemini ekler, bu da papatya zinciri için 'this' döndürür:

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

Güzel cevap, ancak eylemde göstermek için bazı test durumlarını görmek iyi olurdu!
Alnitak

2
Bu cevap çok ilginç ama bir akıllı telefon varken tür 1945 yılında inşa edilmiş bir bilgisayar arayan hatırlatıyor: arr.filter(e => e).
agm1984

@ agm1984 akıllı telefonunuz akıllı değil
Hernán Eche

Bu, smartkeskin bir acı acısına neden olmak için - fiil gibi tanımınıza bağlı olabilir . Bu, yorumunuz nedeniyle telefonumu silahlandırırsam fiziksel acı nedeniyle önemlidir.
agm1984

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

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

İadeler

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

1

For ... in (object-member) döngüsünü 'kötüye kullanma'. => Döngünün gövdesinde yalnızca doğru değerler görünür.

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

kod doğru, yorum yanlış. Kullanma eylemi for ... in, tanımlanmamış anahtarları diziden kaldıran şeydir, ancak aslında burada yalnızca "doğru" değerleri kabul edecek hiçbir kod yoktur
Alnitak

1

Bu size yardımcı olabilir: 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);

Çıktı:

Düğümler üzerinde çalışıyorum

Boş öğeyi diziden kaldırır ve diğer öğeyi görüntüler.


çıktı: 'Düğümler üzerinde çalışıyorum'. boş öğeyi diziden kaldırır ve diğer öğeyi görüntüler.
Jitendra virani

Cevabınızı geliştirdim. Lütfen basit, açık ve okunabilir bir cevap vermeye çalışın;)
GGO

1

Tüm boş elemanların çıkarılması

Bir dizi diğer boş öğelerin yanında boş Nesneler, Diziler ve Dizeler içeriyorsa, bunları aşağıdakilerle kaldırabiliriz:

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

Basit sıkıştırma (bir dizideki boş öğeleri kaldırma)

ES6 ile:

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)

Düz Javascript ile ->

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

Geçersiz girişleri normal ifadeyle filtreleme

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

Bu çalışıyor mu? bir hata gösterir TypeError: [nesne RegExp] bir işlev değil
FreeLightman

0

Boş elemanları çıkarmanın en iyi yolu Array.prototype.filter(), diğer yanıtlarda belirtildiği gibi kullanmaktır .

Ne yazık ki, Array.prototype.filter()IE <9 tarafından desteklenmemektedir. Hala IE8'i veya IE'nin daha eski bir sürümünü desteklemeniz gerekiyorsa , bu tarayıcılarda destek eklemek için aşağıdaki çoklu dolguyu kullanabilirsiniz Array.prototype.filter():

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;
  };
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.