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?
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?
Yanıtlar:
EDIT: Bu soru neredeyse dokuz yıl önce içinde pek çok yararlı yerleşik yöntemler olmadığı zaman cevaplandı Array.prototype
.
Şimdi, kesinlikle, filter
yö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, null
veya undefined
değ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
.
filter
Yönteme, Boolean
yapı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 filter
durumda da, bu, ilk durumda yöntem Boolean
yapıcıyı bir işlev olarak çağırır , değeri dönüştürür ve ikinci durumda filter
yö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, filter
true 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,,,,]);
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ı.
Array.prototype
kullanarak Object.defineProperty
yeni fonksiyonu bir hale getirmek için olmayan enumerable özelliğini ve sonra performans koyarak kaynaklanan hit önlemek .hasOwnProperty
her döngüde.
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]
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("")
yalnızca dizeler tek karakter ise işe yarar
arr.filter(e=>e)
ve bu harita, azaltmak, vb. İle zincirlenebilir
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, " "]
function(e){return !!e}
!!e
NaN (0'dan farklı olarak) içermeyecektir e
(0 gibi).
var myarr=[1, 2,, 3,, 3,undefined,,"",,0, 4,, 4,, 5,, 6,,,,].filter(Boolean);
tanımsız, "" ve 0'ı kaldırır
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]
Boolean
bir işlev olarak çalıştığından emin değilim ...
Boolean
Bir işlev olarak davranırsanız , değer gerçekten / falsy olup olmadığını döndürür true
veya false
döndürür.
(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))
Javascript 1.6 veya üst sürümüne sahipseniz, Array.filter
önemsiz bir return true
geri arama işlevi kullanarak kullanabilirsiniz , örneğin:
arr = arr.filter(function() { return true; });
çünkü .filter
orijinal 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 null
girişleri veya açık bir undefined
değeri olan girişleri kaldırmayacağını , ancak OP'nin özellikle "eksik" girişleri istediğini unutmayın.
undefined
onun verdiği değeri olarak.
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]
[, ,]
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.
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"]
undefined
; bu temelde tüm falsy değerlerini kaldırır.
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 .
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]
@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;
};
}
let newArr = arr.filter(e => e);
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 ...;)
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);
Ben sadece “ES5 en çağrı yukarıda sesimi ekliyorum Array..filter()
küresel kurucu ile” golf-hack ama kullanmanızı öneririz Object
yerine String
, Boolean
ya Number
yukarı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 Object
yapı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 Object
kı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]
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.
Object
kadar return true
metodun 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.
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"]
["", "some string yay", "", "", 123, "Other string yay"].filter(function(n){ return n.length > 0}) //gives your same result removing 123
bu işlevi değiştirme unutmayın. .. iple, ironik olarak, sayıları bırakır ama verilen dizide aynı sonucu verir.
var data = [null, 1,2,3];
var r = data.filter(function(i){ return i != null; })
console.log(r)
[1,2,3]
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
join() === join(',')
:)
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]
*/
for ... in
aslında anahtarların numaralandırılması aslında eksik unsurların atlanmasına neden oluyor. Test, undefined
yalnızca açıkça bu değere ayarlanmış gerçek öğeleri kaldırmaya yarar.
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 } ) ;
arr.filter(e => e)
.
smart
keskin 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.
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);
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
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));
});
};
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.
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))
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)
Geçersiz girişleri normal ifadeyle filtreleme
array = array.filter(/\w/);
filter + regexp
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;
};
}
var a = [,,]
vevar a = [undefined, undefined]
. Birincisi gerçekten boş, ancak ikincisinin aslında iki anahtarı var, ancakundefined
değerlerle.