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

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


当前回答

如果你不想使用include?您可以首先将元素包装在数组中,然后检查包装的元素是否等于数组和包装的元素的交集。这将返回一个基于相等的布尔值。

def in_array?(array, item)
    item = [item] unless item.is_a?(Array)
    item == array & item
end

其他回答

有几个答案建议阵列#包括?,但有一个重要的警告:查看源代码,甚至是Array#include?确实执行循环:

rb_ary_includes(VALUE ary, VALUE item)
{
    long i;

    for (i=0; i<RARRAY_LEN(ary); i++) {
        if (rb_equal(RARRAY_AREF(ary, i), item)) {
            return Qtrue;
        }
    }
    return Qfalse;
}

在不循环的情况下测试单词存在的方法是为数组构造一个trie。有很多trie实现(谷歌“ruby trie”)。我将在本例中使用随机trie:

a = %w/cat dog bird/

require 'rambling-trie' # if necessary, gem install rambling-trie
trie = Rambling::Trie.create { |trie| a.each do |e| trie << e end }

现在,我们已经准备好测试数组中各种单词的存在,而无需在O(log n)时间内对其进行循环,语法简单性与array#include?,使用子线Trie#include?:

trie.include? 'bird' #=> true
trie.include? 'duck' #=> false

这是另一种方法:使用Array#索引方法。

它返回数组中元素第一次出现的索引。

例如:

a = ['cat','dog','horse']
if a.index('dog')
    puts "dog exists in the array"
end

index()也可以采用一个块:

例如:

a = ['cat','dog','horse']
puts a.index {|x| x.match /o/}

这将返回数组中包含字母“o”的第一个单词的索引。

如果需要多次检查任何键,请将arr转换为哈希,然后检查O(1)

arr = ['Cat', 'Dog', 'Bird']
hash = arr.map {|x| [x,true]}.to_h
 => {"Cat"=>true, "Dog"=>true, "Bird"=>true}
hash["Dog"]
 => true
hash["Insect"]
 => false

Hash#has_key的性能?与Array#include相比?

Parameter              Hash#has_key?                 Array#include 

Time Complexity         O(1) operation                O(n) operation 

Access Type             Accesses Hash[key] if it      Iterates through each element
                        returns any value then        of the array till it
                        true is returned to the       finds the value in Array
                        Hash#has_key? call
                        call    

对于一次性检查,使用include?很好

还有另一种方法。

假设数组是[: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'].include? 'Dog'
=> true