如何检查数组的值是否包含一个或多个值?
我正在查看数组中是否有一个或多个值。例如,像这样的东西:如何检查数组的值是否包含一个或多个值?
[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
当然,“包括?”方法只能检查一个值。有没有一种方法来检查多个值?
编辑:我赞同使用该核心Set
classMark 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
[1,2,3,4,5,6].include?(4) and [1,2,3,4,5,6].include?(1)
有什么不对?
Thanks Schwartzie 。你知道是否有更有效的方法来做到这一点? – sjsc 2011-02-04 02:19:56
@StevenXu获得我对优雅的投票。 – Schwartzie 2011-02-04 02:24:42
真的很欣赏试图帮助施瓦茨。再次感谢你。 – sjsc 2011-02-04 02:27:46
>> [1,2,3,4,5,6] & [4,1]
=> [1, 4]
>> [1,2,3,4,5,6] & [7,9]
=> []
>>
@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
这是一组操作。 Set
在标准库中。
require 'set'
a = Set[1,2,3,4,5,6]
b = Set[4,1]
b.subset? a
#=> true
一个快速和肮脏的扩展@ 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)}
我的结论是,减法方法一般是不错的,但由于他们显然实际设置对象超快为这种类型的计算进行了优化。
使用这个脚本: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
基础上胡桃和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
我想久留的回答,而只是抛出一个更加完美的存在:
>> 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
简单,最好的办法:
([4,1] - [1,2,3,4,5 ,6])。空? #=> true
([4,1] - [4,1,6,2])。empty? #=> true
([4,1] - [3,4,7])。empty? #=>假
这将检查是否存在一个数组中的元素:
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
哪个版本的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