Hapus elemen kosong dari array di Javascript

1145

Bagaimana cara menghapus elemen kosong dari array di JavaScript?

Apakah ada cara yang mudah, atau apakah saya perlu mengulanginya dan menghapusnya secara manual?

Tamas Czinege
sumber
14
Akan sangat membantu jika pertanyaan Anda telah menentukan dengan tepat apa yang Anda maksud dengan "elemen kosong", karena sebagian besar jawaban di sini mengartikannya secara tidak benar (IMHO) berarti elemen "falsey". NB: ada perbedaan antara apa yang Anda dapatkan var a = [,,]dan var a = [undefined, undefined]. Yang pertama benar-benar kosong, tetapi yang terakhir sebenarnya memiliki dua kunci, tetapi dengan undefinednilai.
Alnitak

Jawaban:

1065

EDIT: Pertanyaan ini dijawab hampir sembilan tahun yang lalu ketika tidak ada banyak metode built-in yang berguna di Array.prototype.

Sekarang, tentu saja, saya akan merekomendasikan Anda untuk menggunakan filtermetode ini.

Ingatlah bahwa metode ini akan mengembalikan Anda array baru dengan elemen yang melewati kriteria fungsi callback yang Anda berikan kepadanya.

Misalnya, jika Anda ingin menghapus nullatau undefinedmenghargai:

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

Itu akan tergantung pada apa yang Anda anggap "kosong" misalnya, jika Anda berurusan dengan string, fungsi di atas tidak akan menghapus elemen yang merupakan string kosong.

Salah satu pola khas yang saya lihat sering digunakan adalah untuk menghapus elemen yang falsy , yang meliputi string kosong "", 0, NaN, null, undefined, dan false.

Anda bisa meneruskan ke filtermetode, Booleanfungsi konstruktor, atau mengembalikan elemen yang sama di fungsi kriteria filter, misalnya:

var filtered = array.filter(Boolean);

Atau

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

Dalam kedua cara, ini berfungsi karena filtermetode dalam kasus pertama, memanggil Booleankonstruktor sebagai fungsi, mengubah nilai, dan dalam kasus kedua, filtermetode ini secara internal mengubah nilai balik dari callback secara implisit Boolean.

Jika Anda bekerja dengan array jarang, dan Anda mencoba untuk menyingkirkan "lubang", Anda dapat menggunakan filtermetode yang melewati panggilan balik yang mengembalikan true, misalnya:

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

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

Jawaban lama: Jangan lakukan ini!

Saya menggunakan metode ini, memperluas prototipe Array asli:

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

Atau Anda cukup mendorong elemen yang ada ke array lain:

// 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,,,,]);
CMS
sumber
110
PERINGATAN: Opsi ke-2 akan menghapus elemen apa pun dari array yang dianggap "falsy," yaitu nilai false, 0, null & undefined. Array ini akan berakhir tanpa apa-apa di dalamnya: [null ,,, 0,, ​​0,0,0, false, null, 0] walaupun saya mungkin menginginkan elemen dengan nilai 0, seperti dalam array ini: [ 1,0,1,0,0,1]
Jason Bunting
5
Saya menyadari bahwa - itulah sebabnya saya hanya berbicara tentang pilihan kedua. Adapun yang pertama, cakupannya sangat sempit sehingga saya ragu untuk membuatnya menjadi bagian dari prototipe Array. Lihat jawaban Alnitak di halaman ini untuk sesuatu yang lebih ideal. Anda memang memungkinkan untuk melakukan chaining, tentu saja.
Jason Bunting
1
Solusi pertama Anda sangat bagus jika Anda tidak memiliki akses ke metode "filter". Lain saya yakin jawaban Alnitak lebih baik.
Joe Pineda
2
@AlfaTek - selain browser terbaru # 2 akan memiliki kinerja terbaik, karena array di JS sebenarnya bukan array. The splicepanggilan benar-benar mahal di browser lama karena harus nomor baru semua kunci array untuk menutup kesenjangan.
Alnitak
1
@ Hapus tidak, dalam kode modern Anda harus memperpanjang menggunakan dengan aman untuk membuat fungsi baru menjadi properti yang tidak dapat dihitung dan kemudian menghindari kinerja yang disebabkan oleh menempatkan di setiap loop. Array.prototypeObject.defineProperty.hasOwnProperty
Alnitak
1381

Cara sederhana:

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]

atau - (hanya untuk item array tunggal jenis "teks")

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

atau - Cara klasik: iterasi sederhana

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]


via 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 - cara cepat dan keren lainnya (menggunakan 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]

Hapus nilai kosong

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

// ["foo", null, " ", 3, true, [1], Object {}, undefined, ()=>{}]
vsync
sumber
34
Dukungan awal IE untuk filter adalah mode standar IE9.
yincrash
14
untuk javascript murni seharusnyaarr = arr.filter(function(n){return n; });
ilumin
19
foo.join("").split("")sepertinya hanya berfungsi jika string adalah karakter tunggal
Atav32
9
Kode JavaScript murni Anda memiliki bug. Jika array memiliki nilai dengan "0" di dalamnya, nilai tersebut akan disaring karena "0" salah. Yang Anda inginkan adalah: arr.filter (function (n) {return (n! == undefined && n! == null);});
John Kurlak
5
ES6 dapat melakukannya lebih sederhana arr.filter(e=>e)dan ini dapat dirantai dengan peta, mengurangi, dll.
Sheepy
242

Jika Anda perlu menghapus SEMUA nilai kosong ("", null, tidak terdefinisi dan 0):

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

Untuk menghapus nilai kosong dan Line break:

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

Contoh:

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

Kembali:

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

UPDATE (berdasarkan komentar Alnitak)

Dalam beberapa situasi Anda mungkin ingin tetap "0" dalam array dan menghapus yang lain (null, undefined dan ""), ini adalah salah satu cara:

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

Kembali:

["hello", 0, 1, 100, " "]
lepe
sumber
Yup ini bagus karena cuz menghilangkan "" juga.
Vladimirs
3
Fungsi tes bisa sedikit lebih eksplisit:function(e){return !!e}
Koen.
4
@Koen Harap dicatat bahwa !!eakan termasuk NaN (tidak seperti 0) dimana etidak akan (seperti 0).
Sheepy
Tidak benar-benar menjawab pertanyaan yang diajukan.
Alnitak
2
ATAU penggunaan var myarr=[1, 2,, 3,, 3,undefined,,"",,0, 4,, 4,, 5,, 6,,,,].filter(Boolean);menghapus undefined, "" dan 0
Mark Schultheiss
134

Cukup satu liner:

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

atau menggunakan underscorejs.org :

_.filter([1, false, "", undefined, 2], Boolean); // [1, 2]
// or even:
_.compact([1, false, "", undefined, 2]); // [1, 2]
andlrc
sumber
1
Ini sangat keren - saya punya pertanyaan newb: sepertinya Anda menggunakan nama kelas sebagai pemanggilan fungsi - apakah itu typecasting? Saya belum pernah melihat ini sebelumnya dan saya tidak yakin mengapa bisa Booleanberfungsi sebagai fungsi ...
Andrew
8
Jika Anda memperlakukan Booleansebagai fungsi, ia hanya akan mengembalikan trueatau falseapakah nilainya benar / salah.
andlrc
8
Anda tidak memperlakukan Boolean sebagai suatu fungsi; itu adalah fungsi. (Fungsi yang benar-benar normal, kecuali bahwa itu diterapkan secara asli.) Seseorang perlu melakukan sedikit riset tentang model objek JavaScript. ;)
ELLIOTTCABLE
@ELLIOTTCABLE Aku hanya akan meninggalkan ini di sini (true).constructor === Boolean,. Dan kemudian beri tahu saya jika kami bisa melakukan ini dengan build-in lain di JS. ;)) (tentu saja tidak termasuk 5 konstruktor build lainnya. (String, Array, Object, Function, Number))
andlrc
1
Akan gagal baik jika ada nilai 0 dalam array
Sai Ram
129

Jika Anda memiliki Javascript 1.6 atau lebih baru Anda dapat menggunakan Array.filtermenggunakan return truefungsi panggilan balik sepele , misalnya:

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

karena .filtersecara otomatis melewatkan elemen yang hilang dalam array asli.

Halaman MDN yang ditautkan di atas juga berisi versi pemeriksaan kesalahan yang bagus filteryang dapat digunakan dalam penerjemah JavaScript yang tidak mendukung versi resmi.

Perhatikan bahwa ini tidak akan menghapus nullentri atau entri dengan undefinednilai eksplisit , tetapi OP secara khusus meminta entri "hilang".

Alnitak
sumber
Kamu benar! Ini bisa sesederhana ini (dan berfungsi!): Test3 = [1,2,, 3,, 3 ,,, 7 ,,, 7 ,,, 0 ,,, 4,, 4,, 5 ,, 6,, undefined ,, null ,,]; printp ("Menggunakan penyaringan asli array:", test3.filter (fungsi (nilai) {return (value == undefined)? 0: 1;}));
Joe Pineda
3
+1 Seperti yang dikatakan Alnitak, mereka memiliki kode yang dapat digunakan jika tidak tersedia js 1.6
Sameer Alibhai
3
@katsh Saya telah mengklarifikasi - kode di atas tidak berfungsi untuk menghapus entri yang tidak memiliki nilai sama sekali, yang (saya kemudian) pelajari secara semantik berbeda dengan kasus kunci yang ada tetapi yang memiliki undefinednilai yang diberikan.
Alnitak
4
Untuk menghapus entri yang tidak terdefinisi atau null, cukup buat modifikasi kecil ... arr = arr.filter (fungsi (v) {return v;});
Alan CN
4
@AlanCN Anda benar-benar merindukan poin saya. OP diminta untuk menghapus entri yang hilang , sementara sebagian besar jawaban di sini (salah) menghapus entri "falsey".
Alnitak
65

Untuk menghilangkan lubang, Anda harus menggunakan

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

Untuk menghapus nilai hole, dan, falsy (null, undefined, 0, -0, NaN, "", false, document.all):

arr.filter(x => x)

Untuk menghapus lubang, null, dan, tidak terdefinisi:

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]

tsh
sumber
3
Ini harus tinggi dalam jawaban. Bisakah Anda memperluas apa yang Anda maksud dengan lubang / lubang ..?
samayo
2
Lubang @samayo adalah item array yang tidak terisi yaitu[, ,]
Jimmy Obonyo Abor
Dengan menggunakan arr.filter(x => x), JS akan memeriksa apakah x benar atau salah, yaitu if (x), oleh karena itu hanya nilai kebenaran akan ditugaskan ke daftar baru.
KuanYu Chu
56

Cara bersih untuk melakukannya.

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"]
Tomás Senart
sumber
5
Elemen kosong adalah undefined; ini pada dasarnya menghapus semua nilai falsy.
pimvdb
33

ES6 sederhana

['a','b','',,,'w','b'].filter(v => v);
ML13
sumber
1
Ini tidak bekerja: [1, 'two', null, undefined, , NaN, false, true, 0].filter(v => v).
ritsleting
22

Dengan Garis Bawah / Lodash:

Kasus penggunaan umum:

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

Dengan kosong:

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

Lihat dokumentasi lodash untuk tanpa .

kita sendiri
sumber
Masalah dengan #compact adalah menghapus nilai-nilai palsu. Jadi jika array Anda mengandung 0 nilai, mereka juga akan dihapus.
Samuel Brandão
21

ES6Metode adil dan versi yang lebih baru, anggap array di bawah ini:

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

Cara sederhana:

 const clearArray = arr.filter( i => i );
Amerika
sumber
16

Jika menggunakan pustaka adalah opsi, saya tahu underscore.js memiliki fungsi yang disebut compact () http://documentcloud.github.com/underscore/ juga memiliki beberapa fungsi berguna lainnya yang terkait dengan array dan koleksi.

Berikut adalah kutipan dari dokumentasinya:

_.kompak (array)

Mengembalikan salinan array dengan semua nilai falsy dihapus. Dalam JavaScript, false, null, 0, "", undefined dan NaN semuanya palsu.

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

=> [1, 2, 3]

Luis Perez
sumber
Itu juga menghilangkan elemen yang tidak kosong elemen yang didefinisikan seperti 0.
Timothy Gu
15

@Alnitak

Sebenarnya Array.filter bekerja di semua browser jika Anda menambahkan beberapa kode tambahan. Lihat di bawah.

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

Ini adalah kode yang perlu Anda tambahkan untuk IE, tetapi filter dan Pemrograman fungsional nilainya 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;
  };
}
Erik Johansson
sumber
Ini harus menjadi jawaban yang diterima, karena berfungsi di luar kotak. Terima kasih banyak.
Tony
@Tony tidak, seharusnya tidak, karena elemen dengan string kosong di dalamnya tidak sama dengan "elemen kosong", yang terakhir adalah apa yang diminta OP.
Alnitak
14

Karena tidak ada orang lain yang menyebutkannya dan kebanyakan orang memiliki garis bawah yang termasuk dalam proyek mereka, Anda juga dapat menggunakannya _.without(array, *values);.

_.without(["text", "string", null, null, null, "text"], null)
// => ["text", "string", "text"]
Josh Bedo
sumber
12

ES6:

let newArr = arr.filter(e => e);
Kanan Farzali
sumber
8

Anda mungkin merasa lebih mudah untuk mengulang array dan membangun array baru dari item yang ingin Anda simpan dari array daripada dengan mencoba untuk loop dan splice seperti yang disarankan, karena memodifikasi panjang array saat sedang di-loop. lebih dapat menimbulkan masalah.

Anda dapat melakukan sesuatu seperti ini:

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

Sebenarnya di sini ada solusi yang lebih umum:

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]

Anda mendapatkan idenya - Anda kemudian dapat memiliki jenis fungsi filter lainnya. Mungkin lebih dari yang Anda butuhkan, tetapi saya merasa murah hati ...;)

Jason Bunting
sumber
7

Bagaimana dengan ini (ES6): Untuk menghapus nilai Falsy dari 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"]
VIJAY P
sumber
6

Anda harus menggunakan filter untuk mendapatkan array tanpa elemen kosong. Contoh pada ES6

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

Saya hanya menambahkan suara saya di atas “sebut ES5 ini Array..filter()dengan konstruktor global” golf-hack, tapi saya sarankan untuk menggunakan Objectbukan String, Booleanatau Numberseperti yang disarankan di atas.

Secara khusus, ES5 filter()sudah tidak memicu undefinedelemen dalam array; jadi fungsi yang secara universal mengembalikan true, yang mengembalikan semua elemen yang filter()terkena, hanya akan menghasilkan non- undefinedelemen:

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

Namun, menulis ...(function(){return true;})lebih panjang dari menulis ...(Object); dan nilai pengembalian Objectkonstruktor akan, dalam keadaan apa pun , semacam objek. Berbeda dengan konstruktor tinju-primitif yang disarankan di atas, tidak ada nilai objek yang mungkin adalah falsey, dan dengan demikian dalam pengaturan boolean, Objectadalah jalan pintas untuk 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]
DITAWARKAN
sumber
1
WASPADALAH: filter (String) dan filter (Object) tidak memfilter angka nol atau nol. Karena konstruktor juga merupakan fungsi yang Anda dapat lewati String untuk memfilter yaitu someArray.filter(String);sebenarnya setara dengan someArray.filter(function(x){ return String(x); });. Jika Anda ingin menghapus semua nilai falsy someArray.filter(Boolean);berfungsi untuk menghapus 0, -0, NaN, false, '', null, dan undefined.
robocat
1
Jawaban yang bagus, walaupun saya bertanya-tanya tentang kinerja overhead memanggil Objectkonstruktor sebagai lawan return truemetode. @robocat, OP meminta elemen kosong untuk dihapus, bukan nulls.
Alnitak
Saya lebih suka solusi tersingkat, dan paling jelas, kecuali di loop ketat. Preferensi pribadi, saya kira. (=
ELLIOTTCABLE
3

Ketika menggunakan jawaban tertinggi di atas, contoh pertama, saya mendapatkan karakter individual dengan panjang string lebih dari 1. Di bawah ini adalah solusi saya untuk masalah itu.

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

Alih-alih tidak kembali jika tidak ditentukan, kami kembali jika panjangnya lebih besar dari 0. Harapan yang membantu seseorang di luar sana.

Kembali

["some string yay", "Other string yay"]
John Miller
sumber
Memberi +1 karena ini sangat praktis dan persis apa yang biasanya saya perlukan untuk bekerja dengan array string, tetapi perlu diketahui bahwa ini menghapus angka (jika mereka tidak dalam bentuk string) karena mereka tidak memiliki .lenghth, ["", "some string yay", "", "", 123, "Other string yay"].filter(function(n){ return n.length > 0}) //gives your same result removing 123Mengganti fungsi itu. .. dengan String, ironisnya, meninggalkan angka tetapi akan memberikan hasil yang sama dalam array yang Anda berikan.
aamarks
3
var data = [null, 1,2,3];
var r = data.filter(function(i){ return i != null; })

console.log(r) 

[1,2,3]

KARTHIKEYAN.A
sumber
Ini jelas cara yang benar untuk melakukannya dan harus di atas!
Martin Andersson
2

Bagaimana dengan itu:

js> [1,2,,3,,3,,,0,,,4,,4,,5,,6,,,,].filter(String).join(',')
1,2,3,3,0,4,4,5,6
JessyNinja
sumber
6
join() === join(','):)
pimvdb
1

Ini berfungsi, saya mengujinya di AppJet (Anda dapat menyalin-tempel kode pada IDE-nya dan tekan "muat ulang" untuk melihatnya berfungsi, tidak perlu membuat akun)

/* 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]
*/
Joe Pineda
sumber
1
Tampaknya ini hanya berfungsi "secara tidak sengaja", karena ini adalah tindakan penghitungan kunci melalui for ... inyang sebenarnya menyebabkan melewatkan elemen yang hilang. Tes undefinedhanya berfungsi untuk menghapus elemen nyata yang secara eksplisit diatur ke nilai itu.
Alnitak
1

Cara lain untuk melakukannya adalah dengan mengambil keuntungan dari properti panjang array: kemas item-item non-null di 'kiri' array, kemudian kurangi panjangnya. Ini adalah algoritma in-place -tidak mengalokasikan memori, terlalu buruk untuk pengumpul sampah-, dan memiliki perilaku kasus terbaik / rata-rata / terburuk yang sangat baik.

Solusi ini, dibandingkan dengan yang lain di sini, adalah antara 2 hingga 50 kali lebih cepat di Chrome, dan 5 hingga 50 kali lebih cepat di Firefox, seperti yang Anda lihat di sini: http://jsperf.com/remove-null-items-from-array

Kode di bawah ini menambahkan metode 'removeNull' non-enumerable ke Array, yang mengembalikan 'ini' untuk daisy-chaining:

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 } ) ;
GameAlchemist
sumber
Jawaban yang bagus, meskipun akan baik untuk melihat beberapa test case untuk menunjukkannya dalam aksi!
Alnitak
2
Jawaban ini sangat menarik tapi jenis mengingatkan saya melihat sebuah komputer yang dibangun pada tahun 1945 ketika saya memiliki smartphone: arr.filter(e => e).
agm1984
@ agm1984 ponsel cerdas Anda tidak pintar
Hernán Eche
Itu mungkin tergantung pada definisi Anda tentang - smartseperti kata kerja, untuk menyebabkan rasa sakit yang tajam. Ini relevan karena sakit fisik jika saya mempersenjatai ponsel saya karena komentar Anda.
agm1984
1
foo = [0, 1, 2, "", , false, 3, "four", null]

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

kembali

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

'Menyalahgunakan' untuk ... dalam loop (objek-anggota). => Hanya nilai-nilai kebenaran muncul di tubuh loop.

// --- 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);
michael.zech
sumber
kodenya benar, komentarnya salah. Tindakan menggunakan for ... inadalah apa yang menghapus kunci yang tidak terdefinisi dari array, tetapi Anda sebenarnya tidak punya kode di sini untuk hanya menerima nilai "benar"
Alnitak
1

Ini mungkin membantu Anda: https://lodash.com/docs/4.17.4#hapus

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));
            });
        };
Sandeep M
sumber
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);

Keluaran:

Saya sedang mengerjakan nodejs

Ini akan menghapus elemen kosong dari array dan menampilkan elemen lainnya.

Jitendra virani
sumber
output: 'Saya sedang mengerjakan nodejs'. itu akan menghapus elemen kosong dari array dan menampilkan elemen lainnya.
Jitendra virani
Saya meningkatkan jawaban Anda. Coba buat jawaban yang sederhana, jelas, dan mudah dibaca;)
GGO
1

Menghapus semua elemen kosong

Jika array berisi Objek, Array, dan String kosong bersama elemen kosong lainnya, kita bisa menghapusnya dengan:

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

Kompaksi sederhana (menghapus elemen kosong dari array)

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

Dengan Javascript biasa ->

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)

Zlatko Alomerovic
sumber
0

Memfilter entri yang tidak valid dengan ekspresi reguler

array = array.filter(/\w/);
filter + regexp
lcabral
sumber
Apakah ini berhasil? itu menunjukkan kesalahan TypeError: [objek RegExp] bukan fungsi
FreeLightman
0

Cara terbaik untuk menghapus elemen kosong, adalah menggunakan Array.prototype.filter(), sebagaimana telah disebutkan dalam jawaban lain.

Sayangnya, Array.prototype.filter()tidak didukung oleh IE <9. Jika Anda masih perlu mendukung IE8 atau versi IE yang lebih lama, Anda bisa menggunakan polyfill berikut untuk menambahkan dukungan Array.prototype.filter()di browser ini:

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;
  };
}
John Slegers
sumber