Bagaimana cara menghapus elemen kosong dari array?


284

Saya memiliki array berikut

cities = ["Kathmandu", "Pokhara", "", "Dharan", "Butwal"]

Saya ingin menghapus elemen kosong dari array dan menginginkan hasil berikut:

cities = ["Kathmandu", "Pokhara", "Dharan", "Butwal"]

Apakah ada metode seperti compactitu yang akan melakukannya tanpa loop?

Jawaban:


501

Ada banyak cara untuk melakukan ini, salah satunya reject

noEmptyCities = cities.reject { |c| c.empty? }

Anda juga dapat menggunakan reject!, yang akan dimodifikasi citiesdi tempat. Entah itu akan kembali citiessebagai nilai pengembaliannya jika ia menolak sesuatu, atau niljika tidak ada penolakan yang dilakukan. Itu bisa menjadi gotcha jika Anda tidak hati-hati (terima kasih kepada ninja08 karena menunjukkan ini di komentar).


227
Atau jika Anda lebih suka yang lebih ringkascities.reject!(&:empty?)
aNoble

53
hm, kenapa tidak cities.reject!(&:blank?)? empty?untuk array
Nico

27
@Nico blank?hanya tersedia melalui ActiveSupport. Standard Ruby memang menggunakan String#empty?: ruby-doc.org/core-1.9.3/String.html#method-i-empty-3F
Michael Kohl

24
rejectlebih baik daripada reject!karena [].reject!(&:empty?)pengembalian nil, [].reject(&:empty?)pengembalian[]
konyak

17
hati-hati dengan tolak !. menolak! akan mengembalikan nol jika tidak ada perubahan yang dilakukan pada array. Jika Anda ingin mengembalikan array ketika tidak ada perubahan yang dibuat, cukup gunakan tolak tanpa bang.
Nick Res

164
1.9.3p194 :001 > ["", "A", "B", "C", ""].reject(&:empty?)

=> ["A", "B", "C"]

5
Saya lebih suka menggunakan .reject (&: blank?) Untuk menghindari nilai nil juga
ran632

4
@RanGalili blank?adalah pilihan yang baik tetapi railsmetode, dan pertanyaan ini mengenai dataranruby
Swaps

83

Inilah yang bekerja untuk saya:

[1, "", 2, "hello", nil].reject(&:blank?)

keluaran:

[1, 2, "hello"]

Di Ruby 2.3.1 saya mendapatkan NoMethodError: "metode tidak jelas` kosong? ' untuk 1: Fixnum "mencoba menjalankan ini.
Tom

1
@Tom kosong? adalah metode spesifik Rails. Tidak ada di Array untuk ruby ​​biasa. Anda harus menggunakan yang kosong? atau tulis metode Anda sendiri.
jpgeek

@ jpgeek Terima kasih atas klarifikasi, itu adalah masalah yang saya alami :blank?adalah Rails-specific.
Tom

Karena NoMethodError: undefined method empty? for nil:NilClass, :blank? lebih baik daripada:empty?
Lane

:blankbekerja lebih baik daripada :empty. Karena :emptytidak berfungsi untuknil
KBIIX

54

Dalam proyek saya, saya menggunakan delete:

cities.delete("")

5
anggun! sayangnya tidak mengembalikan array yang tersisa, tetapi cukup apik
Kevin

11
Array.delete bersifat kontra-intuitif. Ini beroperasi seperti .delete! () Jika metode seperti itu ada. .Delete () beroperasi langsung pada array dengan cara yang merusak.
scarver2

41

Ketika saya ingin merapikan array seperti ini, saya menggunakan:

["Kathmandu", "Pokhara", "", "Dharan", "Butwal"] - ["", nil]

Ini akan menghapus semua elemen kosong atau nihil.


1
Sebenarnya, jawaban The Tin Man lebih baik karena juga akan menghapus apa pun yang cocok dengan Objek # kosong? yaitu nil, "", "\ n", "", "\ n \ r", dll. Tidak seperti jawaban yang diterima, ia juga akan bekerja tanpa Rails.
superluminary

24

Paling Eksplisit

cities.delete_if(&:blank?)

Ini akan menghapus nilnilai dan nilai string kosong ( "").

Sebagai contoh:

cities = ["Kathmandu", "Pokhara", "", "Dharan", "Butwal", nil]

cities.delete_if(&:blank?)
# => ["Kathmandu", "Pokhara", "Dharan", "Butwal"]

Menghapus tanda baca dan menambahkan tanda titik dua memberi "Kota: hapus jika kosong": D
clapp

2
kosong adalah metode ruby ​​atau rails?
Arnold Roa

2
@ArnoldRoa Ini adalah metode Rails.
PaulMest

1
bagaimana jika ada ruang di antara string kosong?
Steven Aguilar

@StevenAguilar spasi dianggap sebagai panjang 1 (karena spasi adalah karakter). "" .blank? => false
phlegx

23

Coba ini:

puts ["Kathmandu", "Pokhara", "", "Dharan", "Butwal"] - [""]

4
Ini licin, dan tidak mengembalikan ""! Ini adalah trik lil yang hebat.
Sean Larkin

2
["Kathmandu", "Pokhara", "", "Dharan", "Butwal"] - [""] - tidak akan berfungsi dalam kasus ini
ajahongir

2.0.0-p247: 001> ["Kathmandu", "Pokhara", "", "Dharan", "Butwal"] - [""] => ["Kathmandu", "Pokhara", "Dharan", "Butwal "] Tampaknya bekerja untuk saya. Menurut Anda mengapa itu tidak berhasil?
Raels

1
@Raels, string kosong dalam hal ini tidak kosong. Ia memiliki satu ruang di dalamnya.
Chandranshu

1
@ Chandranshu saya mohon berbeda. Saya menyalin dan menempelkan teks ke dalam editor dan menemukan tidak ada ruang di antara tanda kutip seperti yang Anda sarankan. Jika ada, maka mengurangi ["", ""] akan berhasil. Contoh superluminary serupa dan bekerja juga. Permintaan asli adalah untuk menghapus "elemen kosong" bukan "elemen yang kosong", dan contoh elemen kosong ditampilkan di OP sebagai "".
Raels

17

Gunakan reject:

>> cities = ["Kathmandu", "Pokhara", "", "Dharan", "Butwal"].reject{ |e| e.empty? }
=> ["Kathmandu", "Pokhara", "Dharan", "Butwal"]

13
Atau, seperti yang dikatakan Noble di atas reject(&:empty?),.
mu terlalu pendek

Simbol untuk proc lebih lambat dalam 1.8.7 daripada format blok. Ini setara dengan apa yang saya lihat di 1.9.2
Caley Woods

Ini bagus karena akan menghapus elemen apa pun yang cocok dengan Objek # kosong ?, mis. "\ n", "", nil, "\ n \ n \ n", dll ...
superluminary

5
nil.empty?booom break!
Naveed

1
@AllenMaxwell @Naveed Jika array Anda memiliki elemen nil, awali reject(&:empty?)dengan compactmisalnya[nil, ''].compact.reject(&:empty?)
scarver2

14
cities.reject! { |c| c.blank? }

Alasan Anda ingin menggunakan blank?lebih empty?adalah karena kosong mengenali nol, string kosong, dan ruang putih. Sebagai contoh:

cities = ["Kathmandu", "Pokhara", " ", nil, "", "Dharan", "Butwal"].reject { |c| c.blank? }

masih akan kembali:

["Kathmandu", "Pokhara", "Dharan", "Butwal"]

Dan menyerukan empty?pada " "kehendak kembali false, yang mungkin Anda ingin menjadi true.

Catatan: blank?hanya dapat diakses melalui Rails, Ruby hanya mendukung empty?.


11

Sudah ada banyak jawaban tetapi di sini ada pendekatan lain jika Anda berada di dunia Rails:

 cities = ["Kathmandu", "Pokhara", "", "Dharan", "Butwal"].select &:present?

4
present?berasal dari ActiveSupport. Ini memiliki tag tanpa Rails dan membutuhkan permata ekstra untuk satu metode yang tampaknya berlebihan.
Michael Kohl

1
@Naveed, Anda harus mengawali ini dengan "Jika Anda menggunakan RoR". Saya tidak akan menghapusnya karena ini masih informasi yang berguna untuk pemula.
pixelearth

9

Berikut ini satu pendekatan lagi untuk mencapai ini

kita dapat menggunakan presencedenganselect

cities = ["Kathmandu", "Pokhara", "", "Dharan", nil, "Butwal"]

cities.select(&:presence)

["Kathmandu", "Pokhara", "Dharan", "Butwal"]

2
Terima kasih untuk ini. Saya memiliki beberapa " "elemen dalam array saya yang tidak dihapus dengan metode tolak. Metode Anda dihapus nil ""atau " "item.
iamse7en

8

Berikut adalah solusi jika Anda memiliki tipe campuran dalam array Anda:

[nil,"some string here","",4,3,2]

Larutan:

[nil,"some string here","",4,3,2].compact.reject{|r| r.empty? if r.class == String}

Keluaran:

=> ["some string here", 4, 3, 2]


2
 cities = ["Kathmandu", "Pokhara", "", "Dharan", "Butwal"].delete_if {|c| c.empty? } 

hapus dan atur akan menjadi operasi yang mahal
Naveed


0

metode lain:

> ["a","b","c","","","f","g"].keep_if{|some| some.present?}
=> ["a","b","c","f","g"]

-2

Perbarui dengan ketat dengan join&split

cities = ["Kathmandu", "Pokhara", "", "Dharan", "Butwal"]
cities.join(' ').split

Hasilnya adalah:

["Kathmandu", "Pokhara", "Dharan", "Butwal"]

Perhatikan bahwa: ini tidak berfungsi dengan kota dengan spasi


2
Terlihat sangat berisiko!
msdundar

1
Ini pasti akan gagal jika Anda memiliki kota seperti "New York" atau "Naujoji Akmene" :)
Petras L
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.