Làm cách nào để xóa các phần tử trống khỏi một mảng?


284

Tôi có mảng sau

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

Tôi muốn xóa các phần tử trống khỏi mảng và muốn kết quả như sau:

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

Có phương pháp nào như thế compactsẽ làm điều đó mà không cần vòng lặp?

Câu trả lời:


501

Có nhiều cách để làm điều này, một là reject

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

Bạn cũng có thể sử dụng reject!, sẽ sửa đổi citiestại chỗ. Nó sẽ trả về citiesnhư giá trị trả về của nó nếu nó từ chối một cái gì đó, hoặc nilnếu không có từ chối nào được thực hiện. Đó có thể là một vấn đề nếu bạn không cẩn thận (cảm ơn ninja08 vì đã chỉ ra điều này trong các bình luận).


227
Hoặc nếu bạn thích gọn hơncities.reject!(&:empty?)
aNoble

53
hm, tại sao không cities.reject!(&:blank?)? empty?dành cho mảng
Nico

27
@Nico blank?chỉ có sẵn thông qua ActiveSupport. Ruby tiêu chuẩn sử dụng String#empty?: ruby-doc.org/core-1.9.3/String.html#method-i-empty-3F
Michael Kohl

24
rejecttốt hơn là reject![].reject!(&:empty?)trả lại nil, [].reject(&:empty?)trả lại[]
konyak

17
coi chừng từ chối!. Từ chối! sẽ trả về nil nếu không có thay đổi nào được thực hiện cho mảng. Nếu bạn muốn trả về mảng khi không có thay đổi nào được thực hiện, chỉ cần sử dụng từ chối mà không có tiếng nổ.
Nick Res

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

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

5
Tôi muốn sử dụng .reject (&: blank?) Để tránh các giá trị không
ran632

4
@RanGalili blank?là một lựa chọn tốt nhưng là một railsphương pháp và câu hỏi này liên quan đến đồng bằngruby
Hoán đổi

83

Đây là những gì làm việc cho tôi:

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

đầu ra:

[1, 2, "hello"]

Trên Ruby 2.3.1, tôi nhận được NoMethodError: "phương thức không xác định` để trống? ' cho 1: Fixnum "cố gắng thực hiện điều này.
Tom

1
@Tom trống? là một phương pháp cụ thể Rails. Không tồn tại trên Array cho ruby ​​đơn giản. Bạn sẽ phải sử dụng sản phẩm nào? hoặc viết phương pháp của riêng bạn.
jpgeek

@jpgeek Cảm ơn bạn đã làm rõ, đó là rắc rối tôi gặp phải khi nhận ra :blank?là Rails-cụ thể.
Tom

Bởi vì NoMethodError: undefined method empty? for nil:NilClass, :blank? tốt hơn:empty?
Ngõ

:blankhoạt động tốt hơn so với :empty. Bởi vì :emptykhông hoạt động chonil
KBIIX

54

Trong dự án của tôi, tôi sử dụng delete:

cities.delete("")

5
thanh lịch! tiếc là không trả về mảng còn lại, nhưng khá lắt léo
Kevin

11
Array.delete là phản trực quan. Nó hoạt động như một .delete! () Nếu một phương thức như vậy tồn tại. .Delete () hoạt động trực tiếp trên mảng theo cách phá hủy.
Scarver2

41

Khi tôi muốn dọn dẹp một mảng như thế này, tôi sử dụng:

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

Điều này sẽ loại bỏ tất cả các yếu tố trống hoặc không.


1
Trên thực tế, câu trả lời của Tin Man là tốt hơn vì nó cũng sẽ loại bỏ bất cứ thứ gì phù hợp với đối tượng # trống? tức là nil, "", "\ n", "", "\ n \ r", v.v. Không giống như câu trả lời được chấp nhận, nó cũng sẽ hoạt động mà không có Rails.
siêu sáng

24

Rõ ràng nhất

cities.delete_if(&:blank?)

Điều này sẽ loại bỏ cả nilgiá trị và giá trị chuỗi rỗng ( "").

Ví dụ:

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

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

Xóa dấu câu và thêm dấu hai chấm sẽ cho "Thành phố: xóa nếu trống": D
clapp

2
trống là một phương pháp ruby ​​hoặc đường ray?
Arnold Roa

2
@ArnoldRoa Đây là một phương pháp Rails.
PaulMest

1
Nếu có một khoảng trống giữa chuỗi trống thì sao?
Steven Aguilar

@StevenAguilar một khoảng trắng được coi là chiều dài 1 (vì một khoảng trắng là một ký tự). " ".chỗ trống? => sai
đờm

23

Thử cái này:

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

4
Điều này là trơn tru, và không trở lại ""! Đây là một mẹo lil tuyệt vời.
Sean Larkin

2
["Kathmandu", "Pokhara", "", "Dharan", "Butwal"] - [""] - sẽ không hoạt động trong trường hợp này
ajahongir

2.0.0-p247: 001> ["Kathmandu", "Pokhara", "", "Dharan", "Butwal"] - [""] => ["Kathmandu", "Pokhara", "Dharan", "Butwal "] Dường như làm việc cho tôi. Tại sao bạn nghĩ rằng nó không hoạt động?
Raels

1
@Raels, chuỗi trống trong trường hợp này không trống. Nó có một không gian duy nhất trong đó.
Chandranshu

1
@Chandranshu Tôi xin khác. Tôi đã sao chép và dán văn bản vào một trình soạn thảo và thấy rằng không có khoảng trống giữa các trích dẫn như bạn đề xuất. Nếu có, thì trừ ["", ""] sẽ hoạt động. ví dụ của superluminary là tương tự và cũng hoạt động. Yêu cầu ban đầu là xóa "các phần tử trống" chứ không phải "các phần tử trống" và phần tử trống mẫu được hiển thị trong OP là "".
Raels

17

Sử dụng reject:

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

13
Hoặc, như aNoble đã lưu ý ở trên , reject(&:empty?).
mu quá ngắn

Biểu tượng cho Proc chậm hơn trong 1.8.7 so với định dạng khối. Nó ngang tầm với những gì tôi đã thấy trong 1.9.2
Caley Woods

Điều này là tốt vì nó sẽ loại bỏ bất kỳ phần tử nào khớp với Object # trống?, Ví dụ. "\ n", "", nil, "\ n \ n \ n", v.v ...
siêu sáng

5
nil.empty?phá vỡ booom!
Naveed

1
@AllenMaxwell @Naveed Nếu mảng của bạn có các yếu tố bằng không, trước sự reject(&:empty?)với compactví dụ[nil, ''].compact.reject(&:empty?)
scarver2

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

Lý do bạn muốn sử dụng blank?trên empty?là trống mà công nhận con số không, chuỗi rỗng và khoảng trắng. Ví dụ:

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

vẫn sẽ trở lại:

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

Và gọi empty?vào " "sẽ trở lại false, mà bạn có thể muốn được true.

Lưu ý: blank?chỉ có thể truy cập thông qua Rails, Ruby chỉ hỗ trợ empty?.


11

Đã có rất nhiều câu trả lời nhưng đây là một cách tiếp cận khác nếu bạn ở trong thế giới Rails:

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

4
present?xuất phát từ ActiveSupport. Điều này không có thẻ Rails và yêu cầu thêm đá quý cho một phương thức có vẻ quá mức.
Michael Kohl

1
@ Đã lưu, bạn nên mở đầu bằng "Nếu bạn đang sử dụng RoR". Tôi sẽ không tải xuống vì nó vẫn là thông tin hữu ích cho người mới bắt đầu.
pixelearth

9

Đây là một cách tiếp cận để đạt được điều này

chúng ta có thể sử dụng presencevớiselect

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

cities.select(&:presence)

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

2
Cảm ơn vì điều này. Tôi đã có một số " "phần tử trong mảng không bị loại bỏ bằng phương thức từ chối. Phương pháp của bạn loại bỏ nil ""hoặc " "các mục.
iamse7en

8

Đây là một giải pháp nếu bạn có các loại hỗn hợp trong mảng của mình:

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

Giải pháp:

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

Đầu ra:

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

5

Bạn có thể thử cái này

 cities.reject!(&:empty?)

3
có lẽ bạn có nghĩa làcities.reject!(&:blank?)
xguox

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

xóa và sắp xếp sẽ là một hoạt động tốn kém
Naveed


0

Một phương pháp khác:

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

-2

Cập nhật nghiêm ngặt với join&split

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

Kết quả sẽ là:

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

Lưu ý rằng: điều này không hoạt động với một thành phố có không gian


2
Trông rất mạo hiểm!
msdundar

1
Điều này chắc chắn sẽ thất bại nếu bạn có thành phố như "New York" hoặc "Naujoji Akmene" :)
Petras L
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.