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

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


当前回答

您可以尝试:

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

(['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')

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

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

其他回答

还有另一种方法。

假设数组是[: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}[,|.| |]/}

这边怎么样?

['Cat', 'Dog', 'Bird'].index('Dog')

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

%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。

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

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

如果不想循环,则无法使用数组进行循环。您应该改用Set。

require 'set'
s = Set.new
100.times{|i| s << "foo#{i}"}
s.include?("foo99")
 => true
[1,2,3,4,5,6,7,8].to_set.include?(4) 
  => true

设置在内部像Hashes一样工作,因此Ruby不需要在集合中循环查找项,因为顾名思义,它会生成键的哈希值,并创建内存映射,以便每个哈希值指向内存中的某个点。前面的示例使用Hash完成:

fake_array = {}
100.times{|i| fake_array["foo#{i}"] = 1}
fake_array.has_key?("foo99")
  => true

缺点是Set和Hash键只能包含唯一的项,如果你添加了很多项,Ruby将不得不在一定数量的项之后重新散列整个项,以构建适合更大键空间的新映射。有关这方面的更多信息,我建议您观看“MountainWest RubyConf 2014-Nathan Long自制哈希中的大O”。

这里有一个基准:

require 'benchmark'
require 'set'

array = []
set   = Set.new

10_000.times do |i|
  array << "foo#{i}"
  set   << "foo#{i}"
end

Benchmark.bm do |x|
  x.report("array") { 10_000.times { array.include?("foo9999") } }
  x.report("set  ") { 10_000.times { set.include?("foo9999")   } }
end

结果是:

      user     system      total        real
array  7.020000   0.000000   7.020000 (  7.031525)
set    0.010000   0.000000   0.010000 (  0.004816)