我有一个值“狗”和一个数组[“猫”、“狗”、“鸟”]。

如何在不循环的情况下检查数组中是否存在它?是否有一种简单的方法来检查该值是否存在?


当前回答

有趣的事实,

可以使用*检查case表达式中的数组成员资格。

case element
when *array 
  ...
else
  ...
end

注意when子句中的小*,它检查数组中的成员身份。

splat运算符的所有常见魔术行为都适用,所以例如,如果数组实际上不是一个数组,而是一个元素,那么它将匹配该元素。

其他回答

还有另一种方法。

假设数组是[:edit,:update,:create,:show],那么可能就是七宗致命/宁静的罪。

还有一个想法,就是从某个字符串中提取一个有效的动作:

"my brother would like me to update his profile"

然后:

[ :edit, :update, :create, :show ].select{|v| v if "my brother would like me to update his profile".downcase =~ /[,|.| |]#{v.to_s}[,|.| |]/}

如果你想检查一个街区,你可以试试吗?还是全部?。

%w{ant bear cat}.any? {|word| word.length >= 3}   #=> true  
%w{ant bear cat}.any? {|word| word.length >= 4}   #=> true  
[ nil, true, 99 ].any?                            #=> true  

有关详细信息,请参见Enumerable。

我的灵感来自于“评估数组中是否有任何项目”

有一个入口?正如@campeterson所指出的,ActiveSupport(Rails的一部分)中的方法。因此,在Rails中,或者如果您需要“active_support”,您可以编写:

'Unicorn'.in?(['Cat', 'Dog', 'Bird']) # => false

OTOH,没有in运算符或#in?尽管Ruby内核的顶级成员Yusuke Endoh之前就提出过这种方法,但这种方法在Ruby本身也是如此。

正如其他人所指出的,相反的方法包括?存在,对于所有枚举,包括Array、Hash、Set、Range:

['Cat', 'Dog', 'Bird'].include?('Unicorn') # => false

请注意,如果数组中有许多值,则将逐个检查这些值(即O(n)),而查找哈希值的时间将是恒定的(例如O(1))。例如,如果数组是常量,最好使用Set。例如:

require 'set'
ALLOWED_METHODS = Set[:to_s, :to_i, :upcase, :downcase
                       # etc
                     ]

def foo(what)
  raise "Not allowed" unless ALLOWED_METHODS.include?(what.to_sym)
  bar.send(what)
end

快速测试显示,呼叫包括?在10个元素上调用Set比在等效数组上调用Set快3.5倍(如果找不到元素)。

最后一点:使用include时要小心?在Range上,有一些微妙之处,所以请参考文档并与封面进行比较?。。。

您可以尝试:

示例:如果阵列中存在猫和狗:

(['Cat','Dog','Bird'] & ['Cat','Dog'] ).size == 2   #or replace 2 with ['Cat','Dog].size

而不是:

['Cat','Dog','Bird'].member?('Cat') and ['Cat','Dog','Bird'].include?('Dog')

注:成员?包括?都是一样的。

这可以在一条线上完成工作!

array = [ 'Cat', 'Dog', 'Bird' ]
array.include?("Dog")