Ruby中Array.empty?或[] .empty?的相反方法是什么?

70

我知道我可以这样做

unless [1].empty? 

不过我想知道是否有一种方法?


可能是Ruby non_empty?方法的重复问题。 - knut
5个回答

101

除了像davidrac提到的#any?,使用ActiveSupport还有一个更类似于其他语言中的真值测试的方法#present?。对于 nil, false, '', {}, [] 等返回 false;对于其他所有情况都返回true(包括 0,这很有趣)。


2
如果您可以访问ActiveSupport,则#present?很可能是您最好的选择。 - Travis
2
另外一个支持这个答案的人:当你在使用 ActiveSupport(例如在Rails应用程序中)时,你可以使用#present?来满足你的需求。但是#present?的相反操作实际上应该是#blank?而不是#empty?。#blank?具有与答案中枚举的#present?相同的“空值”定义... - severin
12
any?比起![].empty?会慢一些因为any?需要检查是否存在nil元素。虽然present?blank?很好用,但它们也较慢,因为它们必须检查元素是否respond_to?(:empty)。没有真正的empty?的反义词。 - Schneems
Rails指南描述了#present? - rudolph9
@Schneems 我很想看看这些的基准测试。 - Joshua Pinter
随意运行它们自己 https://github.com/evanphx/benchmark-ips - Schneems

24

您可以使用[1].any?,它实际上是在Enumerable中定义的。

请注意,如果您的数组仅包含nilfalse值,则此方法将不起作用。


8
[nil].any?
=> false
[nil].any? {|something| true}
=> true
[].any? {|something| true}
=> false
[false, false].any? {|something| true}
=> true
[nil, 'g'].any? {|something| true}
=> true

2
这个答案真的很令人困惑。返回 true 的代码片段之所以这样做,只是因为块内的返回值,而不是数组内的值。(示例 4 和 5 是相同的)。在示例 3 中,该块从未执行,因为数组为空。 - lcjury

3

我知道的没有一种单一的方法可以在Ruby中实现这一点。关键词是“单一”:

[5].size.positive? => true
[5].size.nonzero? => 1

[].size.positive? => false
[].size.nonzero? => nil

使用安全导航操作符后,这两种方法变得更加有用,因为nil返回假值,意味着负面的方法(如#empty?)会有些问题:

# nil considered 'not empty' isn't usually what you want
not_empty = proc{|obj| !obj&.empty? }

not_empty.call nil => true
not_empty.call [ ] => false
not_empty.call [5] => true


# gives different 3 answers for the 3 cases
# gives truthy/falsy values you'd probably expect
positive_size = proc{|obj| obj&.size&.positive? }

positive_size.call nil => nil
positive_size.call [ ] => false
positive_size.call [5] => true


# gives truthy/falsy values you'd probably expect
nonzero_size = proc{|obj| obj&.size&.nonzero? }

nonzero_size.call nil => nil
nonzero_size.call [ ] => nil
nonzero_size.call [5] => 1

2

检查数组中是否存在元素:
.empty? (空?)
.present?(存在?)

如果 a={}
a.any? .nil?
将会返回 false。

检查字段是否具有非 nil 值:

.present?
.nil?
.any?

9
请注意,present? 是 Rails / ActiveSupport 中的方法,而不是核心 Ruby 中的方法。 - Paul Annesley

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