如何检查Ruby数组是否包含多个值中的一个?
我有两个Ruby数组,我需要看看它们是否有共同的值。我可以循环遍历一个数组中的每个值,并在另一个数组中包含?(),但我相信有更好的方法。这是怎么一回事?(两个数组都包含字符串。) 谢谢。他们: 下面是一个例子:如何检查Ruby数组是否包含多个值中的一个?,ruby,string,arrays,intersect,Ruby,String,Arrays,Intersect,我有两个Ruby数组,我需要看看它们是否有共同的值。我可以循环遍历一个数组中的每个值,并在另一个数组中包含?(),但我相信有更好的方法。这是怎么一回事?(两个数组都包含字符串。) 谢谢。他们: 下面是一个例子: > a1 = [ 'foo', 'bar' ] > a2 = [ 'bar', 'baz' ] > a1 & a2 => ["bar"] > !(a1 & a2).empty? # Returns true if there are any
> a1 = [ 'foo', 'bar' ]
> a2 = [ 'bar', 'baz' ]
> a1 & a2
=> ["bar"]
> !(a1 & a2).empty? # Returns true if there are any elements in common
=> true
有共同的价值吗?可以使用“交点”操作符: 但是,如果您正在寻找一个完整的交叉点(使用重复的交叉点),则问题更为复杂,这里已经存在堆栈溢出: 或定义“真实交叉点”并验证以下测试的quick
class ArrayIntersectionTests < Test::Unit::TestCase
def test_real_array_intersection
assert_equal [2], [2, 2, 2, 3, 7, 13, 49] & [2, 2, 2, 5, 11, 107]
assert_equal [2, 2, 2], [2, 2, 2, 3, 7, 13, 49].real_intersection([2, 2, 2, 5, 11, 107])
assert_equal ['a', 'c'], ['a', 'b', 'a', 'c'] & ['a', 'c', 'a', 'd']
assert_equal ['a', 'a', 'c'], ['a', 'b', 'a', 'c'].real_intersection(['a', 'c', 'a', 'd'])
end
end
class ArrayIntersectionTests
使用交叉口看起来不错,但效率很低。我会在第一个数组中使用“any?”(这样当在第二个数组中找到一个元素时,迭代就会停止)。另外,在第二个数组上使用集合可以快速进行成员身份检查。i、 e:
a = [:a, :b, :c, :d]
b = Set.new([:c, :d, :e, :f])
c = [:a, :b, :g, :h]
# Do a and b have at least a common value?
a.any? {|item| b.include? item}
# true
# Do c and b have at least a common value?
c.any? {|item| b.include? item}
#false
试试这个
a1 = [ 'foo', 'bar' ]
a2 = [ 'bar', 'baz' ]
a1-a2 != a1
true
数组#相交?(Ruby 3.1+)
从Ruby 3.1开始,有一个新的数组#intersect?
方法,
它检查两个数组是否至少有一个共同元素
以下是一个例子:
> a1 = [ 'foo', 'bar' ]
> a2 = [ 'bar', 'baz' ]
> a1 & a2
=> ["bar"]
> !(a1 & a2).empty? # Returns true if there are any elements in common
=> true
a=[1,2,3]
b=[3,4,5]
c=[7,8,9]
#3是公共元素
a、 相交?(b)
#=>正确
#没有共同点
a、 相交?(c)
#=>错误
另外,Array#intersect?
可以比备选方案快得多,因为它避免创建中间数组,一旦找到公共元素就会返回true,它是用C实现的
来源:
any?
在这种情况下有效,但在处理false
和nil
值时无效:[nil,false]。any?#=>false
。有没有更整洁的方法来执行!(a1和a2).空?
?@DavidWest yes,(a1和a2).当前?
。基准测试表明,根据简单的值与对象属性比较,这比(更美观的)集合相交方法快1.5-2倍。使用any?
而不是empty?
设置交叉点,正如上面一条评论中所建议的,略有不同,但没有改变结果。(严格考虑性能,并且正如预期的那样,因为any?
在第一场比赛中退出。)
a1 = [ 'foo', 'bar' ]
a2 = [ 'bar', 'baz' ]
a1-a2 != a1
true