如何从数组中删除空白元素?


283

我有以下数组

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

我想从数组中删除空白元素,并希望得到以下结果:

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

有没有这样的方法compact可以做到没有循环?

Answers:


501

有很多方法可以做到这一点,一种是 reject

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

您也可以使用reject!,它将cities在适当位置进行修改。它要么返回cities作为它的返回值,如果它拒绝的东西,或者nil如果没有拒绝制成。如果您不小心的话,这可能是一个陷阱(感谢ninja08在评论中指出了这一点)。


227
或者,如果你喜欢更紧凑cities.reject!(&:empty?)
aNoble

53
嗯,为什么不cities.reject!(&:blank?)呢?empty?用于阵列
Nico 2012年

27
@Nico blank?仅可通过访问ActiveSupport。标准Ruby确实使用String#empty?ruby-doc.org/core-1.9.3/String.html#method-i-empty-3F
Michael Kohl

24
reject好过reject!,因为[].reject!(&:empty?)回报率nil[].reject(&:empty?)回报[]
konyak

17
当心拒绝!拒绝!如果未对数组进行任何更改,则将返回nil。如果要在未进行任何更改的情况下返回数组,则只需使用reject即可。
Nick Res

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

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

5
我更喜欢使用.reject(&:blank?)来避免nil值
ran632

4
@RanGalili blank?是一个不错的选择,但是它是一种rails方法,这个问题是关于平原的ruby
掉期

83

这对我有用:

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

输出:

[1, 2, "hello"]

在Ruby 2.3.1上,我得到NoM​​ethodError:“未定义的方法'空白?' 对于1:Fixnum”,则尝试执行此操作。
汤姆(Tom)

1
@汤姆空白?是特定于Rails的方法。普通红宝石在Array上不存在。您将不得不使用空吗?或编写自己的方法。
jpgeek

@jpgeek感谢您的澄清,这就是我在实现:blank?特定于Rails时遇到的麻烦。
汤姆(Tom)

因为NoMethodError: undefined method empty? for nil:NilClass:blank? 优于:empty?
Lane

:blank效果比:empty。因为:empty不适用于nil
KBIIX

54

在我的项目中,我使用delete

cities.delete("")

5
优雅!不幸的是,它没有返回剩余的数组,而是非常漂亮
Kevin

11
Array.delete是违反直觉的。如果存在这样的方法,它将像.delete!()一样运行。.delete()以破坏性的方式直接在数组上运行。
scarver2

41

当我想整理这样的数组时,我使用:

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

这将删除所有空白或零元素。


1
实际上,“铁皮人”的答案更好,因为它还会删除任何与Object#blank相匹配的内容?即nil,“”,“ \ n”,“”,“ \ n \ r”等。与公认的答案不同,它也可以在没有Rails的情况下工作。
superluminary

24

最明确的

cities.delete_if(&:blank?)

这将同时删除nil值和空字符串("")值。

例如:

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

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

删除标点符号并添加冒号,将得出“城市:如果空白则删除”:D
clapp

2
空白是红宝石还是铁轨方法?
阿诺德·罗阿2015年

2
@ArnoldRoa这是一种Rails方法。
PaulMest

1
如果空字符串之间有空格怎么办?
史蒂芬·阿吉拉尔

@StevenAguilar空格被认为是长度1(因为空格是字符)。”“。空白?=>假
phlegx

23

尝试这个:

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

4
这很漂亮,并且不会返回“”!这是个很棒的小把戏。
肖恩·拉金

2
[“加德满都”,“博克拉”,“”,“达兰”,“布特瓦尔”]-[“”]-在这种情况下将无法使用
ajahongir 2014年

2.0.0-p247:001> [“加德满都”,“博克拉”,“”,“达兰”,“布特瓦尔”]-[“”] => [“加德满都”,“博克拉”,“达兰”,“布特瓦尔“]似乎为我工作。您为什么认为它不起作用?
Raels

1
@Raels,这种情况下的空白字符串不为空。它内部只有一个空间。
Chandranshu 2014年

1
@Chandranshu,我希望与众不同。我将文本复制并粘贴到编辑器中,发现引号之间没有空格,如您所建议。如果存在,则减去[“”,“”]将起作用。superluminary的示例与此类似,并且也可以使用。最初的请求是删除“空白元素”,而不是“空白元素”,示例空白元素在OP中显示为“”。
Raels

17

用途reject

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

13
或者,如aNoble上面提到的,reject(&:empty?)
亩太短,

从1.8.7到proc的符号比块格式慢。它与我在1.9.2中看到的水平相当
Caley Woods,

这样很好,因为它将删除任何与Object#empty?相匹配的元素。“ \ n”,“”,nil,“ \ n \ n \ n”等…
superluminary

5
nil.empty?break!
2014年

1
@AllenMaxwell @Naveed如果您的数组有nil个元素,则在其前面reject(&:empty?)加上compact例如[nil, ''].compact.reject(&:empty?)
scarver2

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

您要使用blank?over 的原因empty?是,空格可以识别nil,空字符串和空格。例如:

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

仍会返回:

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

并呼吁empty?" "将返回false,这你可能想true

注意:blank?仅可通过Rails访问,Ruby仅支持empty?


11

已经有了很多答案,但是如果您在Rails世界中,这是另一种方法:

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

4
present?来自ActiveSupport。这没有no Rails标记,一种方法需要额外的gem似乎过多。
Michael Kohl 2012年

1
@Naveed,您应该在此之前添加“如果您正在使用RoR”。我不会拒绝它,因为它对于初学者仍然是有用的信息。
pixelearth

9

这是实现此目的的另一种方法

我们可以使用presenceselect

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

cities.select(&:presence)

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

2
这次真是万分感谢。" "我的数组中有一些元素没有被拒绝方法删除。您的方法已删除nil """ "项目。
iamse7en 2015年

8

如果您的数组中有混合类型,这是一个解决方案:

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

解:

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

输出:

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

5

你可以试试看

 cities.reject!(&:empty?)

3
也许您的意思是cities.reject!(&:blank?)
xguox

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

删除和整理将是一项昂贵的操作
Naveed 2012年


0

另一种方法:

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

-2

join&严格更新split

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

结果将是:

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

请注意:这不适用于有空间的城市


2
看起来很有风险!
msdundar

1
如果您有“ New York”或“ Naujoji Akmene”之类的城市,这肯定会失败:)
Petras L
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.