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?

ashisrai_
sumber

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

Matt Greer
sumber
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"]
pengguna2010324
sumber
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"]
Kimeen
sumber
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("")
esio
sumber
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.

superluminary
sumber
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"]
dahak
sumber
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"] - [""]
Raels
sumber
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"]
Manusia Timah
sumber
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?.

Colton Fent
sumber
11

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

 cities = ["Kathmandu", "Pokhara", "", "Dharan", "Butwal"].select &:present?
Naveed
sumber
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"]
Sampat Badhe
sumber
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]
Francois
sumber
5

Anda bisa Coba ini

 cities.reject!(&:empty?)
anusha
sumber
3
mungkin cities.reject!(&:blank?)
maksudmu
2
 cities = ["Kathmandu", "Pokhara", "", "Dharan", "Butwal"].delete_if {|c| c.empty? } 
suren
sumber
hapus dan atur akan menjadi operasi yang mahal
Naveed
2

Cara terpendek cities.select(&:present?)

Javier Segovia
sumber
0

metode lain:

> ["a","b","c","","","f","g"].keep_if{|some| some.present?}
=> ["a","b","c","f","g"]
p4ndravitasi
sumber
-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

Hieu Pham
sumber
2
Terlihat sangat berisiko!
msdundar
1
Ini pasti akan gagal jika Anda memiliki kota seperti "New York" atau "Naujoji Akmene" :)
Petras L