在Ruby中删除数组中的nil和空字符串

50

我是一名新手,正在学习 Ruby,但遇到了困难。假设我有一个像这样的数组:

arr = [1, 2, 's', nil, '', 'd']

我希望你能将其中的 nil 和空字符串删除,即最终数组应为:

arr = [1, 2, 's', 'd']

我尝试了compact但它会产生这样的结果:
arr.compact!
arr #=> [1, 2, 's', '', 'd'] doesn't remove empty string.

我想知道在Ruby中是否有聪明的方法来做到这一点。


我检查了一下,它没有nil,你怎么同时移除nil和空字符串。这个是重复的吗? - user4093799
2
是的,blank? 可以使用,但在普通的 Ruby 中不可用。它是 Rails 的一部分。 - awendt
3
为什么要踩?人们至少应该给出一个踩的解释,难道这就是社区帮助新人的方式吗? - user4093799
3
我也不理解为什么会有负评。这不是重复的问题(在我看来,即使是重复的问题也不应该是负评的理由),问题表述清楚,而且很明显你尝试过寻找自己的解决方法。 - awendt
@Зелёный 在 Ruby 中不能使用空白符,请注意。 :) - user4093799
显示剩余9条评论
13个回答

58

你可以这样做:

arr.reject { |e| e.to_s.empty? } #=> [1, 2, "s", "d"]

注意 nil.to_s => ''


8
对于那些先看到这个答案的人:根据 https://dev59.com/I18e5IYBdhLWcg3wFnLm#41810889,更简单的方法是使用 arr.reject(&:blank?) - lucas
啊!谢谢Cary,是我错了!我太匆忙了,没有看到链接答案中的评论。希望我的评论仍然能帮助像我这样匆忙通过谷歌搜索在Rails中最好的方法的人们。也许这不是提问的地方,但为什么更喜欢引用一个(可能会改变)的句柄而不是直接链接到答案呢? - lucas
2
:blank?只能在Rails中使用,因为它是ActiveSupport方法而不是Ruby的一部分。 - pankajdoharey

27

由于您想要删除nil和空字符串,所以它不是如何从数组中删除空元素?的重复问题。

您需要使用.reject

arr = [1, 2, 's', nil, '', 'd']
arr.reject { |item| item.nil? || item == '' }
注意:reject函数和加上感叹号的reject!函数的行为与带有或没有感叹号的compact函数相同: reject!compact!会修改数组本身,而rejectcompact会返回数组的副本并保留原始数组不变。

如果您使用Rails,则还可以使用blank?函数。它专门设计用于处理nil,因此方法调用变为:

arr.reject { |item| item.blank? }

2
整数不响应 empty? - xlembouras
哦,你说得完全正确。感谢指出这个问题。我已经更新了答案。 - awendt
不能点赞因为声望太低,但这也是一个不错的答案。另外,谢谢你的建议,但我现在不使用Rails。 :) - user4093799
9
这是我点赞的答案。我喜欢使用它的方式是 arr.reject &:blank? - Boris Stitnicky
对于旧版本的 Ruby,您可以使用 empty? 代替 blank? - Wylliam Judd
arr.reject {|e| e.to_s == ''} is probably easier than e.nil? || e == '' - Rob Kinyon

26

我倾向于做:

arr = [1, 2, 's', nil, '', 'd']
arr.reject(&:blank?)

返回:

=> [1, 2, "s", "d"]

无法将其留空,因为它不适用于整数或nil类。 - Salman

12

compact_blank(Rails 6.1+)

如果您正在使用 Rails(或独立的 ActiveSupport),从版本 6.1 开始,有一个 compact_blank 方法可从数组中删除 blank 值。

它在底层使用 Object#blank? 来确定项是否为空白。

[1, 2, 's', nil, '', 'd'].compact_blank
# => [1, 2, 's', 'd']

[1, "", nil, 2, " ", [], {}, false, true].compact_blank
# => [1, 2, true]

这里有一个文档链接和一个相关PR的链接

还提供了一种具有破坏性的变体。请参见Array#compact_blank!


1
不错的发现!这给我们升级到Rails 6.1提供了另一个好理由。 - Joshua Pinter

8

arr.reject(&:blank?)

只需使用这个,不需要其他任何东西。


3
blank 不是 Ruby 的方法,而是 Rails 的方法,所以您需要添加所需的 active_support 库,且该问题标记为 Ruby 而不是 Rails。无论如何,这个答案重申了之前指出的问题。 - Sebastián Palma

4
您也可以使用-来删除所有的nil''元素:
arr -= [nil, '']
#=> [1, 2, "s", "d"]

演示

或使用快捷方式compactreject如果您没有使用Rails,则可以使用arr.reject(&:blank?)

arr = arr.compact.reject(&''.method(:==))
#=> [1, 2, "s", "d"]

示范

(注:此链接为英文网站)

2
你可以使用 reject 来压缩。
arr = [1, 2, 's', nil, '', 'd']
arr = [1, 2, 's', 'd']

arr = arr.compact.reject { |h| h == "" }

或者

arr = arr.compact.delete_if { |h| h == "" }

2
这个最简单和快速的方法是:
arr = [1, 2, 's', nil, '', 'd'] - [nil,'']

==> arr = [1, 2, 's', 'd']

1

你可以在Ruby中使用compact和delete_if方法来移除数组中的nil和空字符串。

arr = [1, 2, 's', nil, '', 'd']
arr.compact!.delete_if{|arrVal| arrVal.class == String and arrVal.empty?}
=> [1, 2, "s", "d"]

0
希望这对你有用:
arr = [1, 2, 's', nil, '', 'd']
arr.select{|x| x.to_s!="" }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接