我正在查看數組中是否有一個或多個值。例如,像這樣的東西:如何檢查數組的值是否包含一個或多個值?
[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
當然,「包括?」方法只能檢查一個值。有沒有一種方法來檢查多個值?
我正在查看數組中是否有一個或多個值。例如,像這樣的東西:如何檢查數組的值是否包含一個或多個值?
[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