Comparing 2 arrays of symbols
I'm new to ruby, and I've been googling for hours, but I can't figure this one out. It looks like it should be really easy so I'm getting pretty frustrated.
I'm working in ruby and need to comp开发者_C百科are 2 arrays of symbols for a true or false return.
array1 = [:a, :c]
array2 = [:a, :b, :c]
The comparison I need to do, is to see if array2 includes all the elements of array1. In this case array2 includes array1, but array1 does not include array2.
I tried:
array2.to_s.include?(array1.to_s)
Which only returns true if they are in the same order because it needs to convert to a string for comparison. So as is it returns false (not what I'm looking for), but if array2 = [:a, :c, :b] it would be true. Is there a more appropriate way of making this comparison?
venj's answer is fine for small arrays but might not perform well (this is debatable) for large arrays. Since you're basically doing a set operation ("is Set(array1) a subset of Set(array2)?"), it makes sense to see how Ruby's own Set library does this. Set has a subset?
method, and taking a peek at its source we see that it's short and sweet:
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
We could just instantiate two Set objects from the arrays and call it a day, but it's just as easy to distill it into a oneliner that operates directly on them:
array1 = [:a, :c]
array2 = [:a, :b, :c]
array1.length < array2.length && array1.all? {|el| array2.include? el }
# => true
array1 << :z
array1.length < array2.length && array1.all? {|el| array2.include? el }
# => false
You can use -. e.g.:
array1 - array2 #=> returns empty array, if array2 include all array1 elements.
Hope this can solve your problem.
You can add this method to the Array class.
#!/usr/bin/env ruby
class Array
def includes_other(arr)
raise "arr must be an Array" unless arr.kind_of? Array
return (arr - self).length == 0
end
end
arr1 = [:a, :c, :e]
arr2 = [:e, :a, :c, :d]
puts arr2.includes_other(arr1) # prints true
arr3 = [:x, :c, :e]
puts arr3.includes_other(arr1) # prints false
精彩评论