2011-02-04 135 views
21

我正在查看数组中是否有一个或多个值。例如,像这样的东西:如何检查数组的值是否包含一个或多个值?

[1,2,3,4,5,6].include?([4,1]) # => true 
[4,1,6,2].include?([4,1]) # => true 
[3,4,7].include?([4,1]) # => false 

当然,“包括?”方法只能检查一个值。有没有一种方法来检查多个值?

+0

哪个版本的Ruby你在这里使用? 我每次都得到错误。 (主):006:0> [1,2,3,4,5,6] .include?([4,1]) => false irb(main):007:0> [4, 1,6,2] .include?([4,1]) => false irb(main):008:0> [3,4,7] .include?([4,1]) – ram 2016-02-23 07:09:45

回答

15

编辑:我赞同使用该核心SetclassMark Thomas'替代的解决方案。

尽管我的解决方案更加严格地回答了如何在数组中执行此操作的问题,但sjsc可能会从审阅自己的案例和探索使用集合的选项中受益。

有很多有效的reasond使用数组(维护顺序,允许重复),但以下仍然足够,但如果这些都不涉及,sjsc可能实际上受益于使用Set而不是Array,并且在某种程度上,马克的解决方案在语义上更胜一筹。


我不知道这样做的任何库方法,但它不会太难编写自己的函数。

class Array 
    def subset?(a) 
    (self - a).length == 0 
    end 
end 

我相信有计算更有效的方法来完成这个,但这应该做你想要的。

做阵列交集工作,基本上相同的事情。

class Array 
    def subset?(a) 
    (self & a).length == length 
    end 
end 

优化在这个级别是没有什么帮助的事项太多了,但你不想做的就是开始比较阵列多次:

class Array 
    # don't do this 
    def subset?(a) 
    (self & a) == a 
    end 
end 
3

[1,2,3,4,5,6].include?(4) and [1,2,3,4,5,6].include?(1)有什么不对?

+0

Thanks Schwartzie 。你知道是否有更有效的方法来做到这一点? – sjsc 2011-02-04 02:19:56

+0

@StevenXu获得我对优雅的投票。 – Schwartzie 2011-02-04 02:24:42

+0

真的很欣赏试图帮助施瓦茨。再次感谢你。 – sjsc 2011-02-04 02:27:46

57
>> [1,2,3,4,5,6] & [4,1] 
=> [1, 4] 
>> [1,2,3,4,5,6] & [7,9] 
=> [] 
>> 
1

@kurumi具有正确的,但我想我要补充的时候我只想要一个数组的一个子集(通常是哈希键虽然)我有时会使用这个小扩展:

class Hash 
    # Usage { :a => 1, :b => 2, :c => 3}.except(:a) -> { :b => 2, :c => 3} 
    def except(*keys) 
    self.reject { |k,v| 
     keys.include? k 
    } 
    end 

    # Usage { :a => 1, :b => 2, :c => 3}.only(:a) -> {:a => 1} 
    def only(*keys) 
    self.dup.reject { |k,v| 
     !keys.include? k 
    } 
    end 
end 

class Array 
    def except(*values) 
    self.reject { |v| 
     values.include? v 
    } 
    end 

    def only(*values) 
    self.reject { |v| 
     !values.include? v 
    } 
    end 
end 
25

这是一组操作。 Set在标准库中。

require 'set' 

a = Set[1,2,3,4,5,6] 
b = Set[4,1] 

b.subset? a 
#=> true 
6

一个快速和肮脏的扩展@ Schwartzie的做法:

larger_array = [1,2,3,4,5,6] 
smaller_array = [4,1] 
smaller_array.all? {|smaller_array_item| larger_array.include?(smaller_array_item)} 
2

我的结论是,减法方法一般是不错的,但由于他们显然实际设置对象超快为这种类型的计算进行了优化。

使用这个脚本:https://gist.github.com/1996001

我这些基准测试结果(关于Ruby 1.9。2p290):

SUBTRACTION 
- subset 
    0.180000 0.000000 0.180000 ( 0.189767) 
- partial subset 
    0.170000 0.000000 0.170000 ( 0.178700) 
- non subset 
    0.180000 0.000000 0.180000 ( 0.177606) 

INTERSECTION 
- subset 
    0.190000 0.000000 0.190000 ( 0.194149) 
- partial subset 
    0.190000 0.000000 0.190000 ( 0.191253) 
- non subset 
    0.190000 0.000000 0.190000 ( 0.195798) 

SET 
- subset 
    0.050000 0.000000 0.050000 ( 0.048634) 
- partial subset 
    0.040000 0.000000 0.040000 ( 0.045927) 
- non subset 
    0.050000 0.010000 0.060000 ( 0.052925) 

这一点我认为非常惊人的,特别是如果你看看来源:

# File 'lib/set.rb', line 204 

def subset?(set) 
    set.is_a?(Set) or raise ArgumentError, "value must be a set" 
    return false if set.size < size 
    all? { |o| set.include?(o) } 
end 

通过:http://rubydoc.info/stdlib/set/1.9.2/Set#subset%3F-instance_method

4

基础上胡桃和spyle的建议,这里是我的测试:

([1,2,3,4,5,6] & [4,1])。any? #=> true

但是,.any?会变成任何对象为true

([1,2,3,4,5,6] & [6,7])。任何? #=>真

所以我觉得这里可能是一个正在运行的:

([1,2,3,4,5,6] & [6,7] )。长度== [6,7]。长度#=>假

(bigger_array & smaller_array)。长度== smaller_array.length

2

我想久留的回答,而只是抛出一个更加完美的存在:

>> set1 = [1,2,3,4,5,6] 
[ 
    [0] 1, 
    [1] 2, 
    [2] 3, 
    [3] 4, 
    [4] 5, 
    [5] 6 
] 
>> set2 = [4,1] 
[ 
    [0] 4, 
    [1] 1 
] 
>> set1.any?{ |num| set2.include?(num) } 
true 
>> set2 = [8,9] 
[ 
    [0] 8, 
    [1] 9 
] 
>> set1.any?{ |num| set2.include?(num) } 
false 
0

简单,最好的办法:

([4,1] - [1,2,3,4,5 ,6])。空? #=> true

([4,1] - [4,1,6,2])。empty? #=> true

([4,1] - [3,4,7])。empty? #=>假

0

这将检查是否存在一个数组中的元素:

students = ["jim", "bob", "sally"] 
teachers = ["mrs. jones", "mrs. sharpe", "mrs. ray"] 

puts "what's your name ?" 
answer = gets.chomp 

if answer.include?(students.to_s) 
    puts "you are a student" 

elsif 
    puts "you are a teacher" 

end 
相关问题