1

I am using Ruby on Rails 3.0.7 and I would like to check if each element of an array is included in a set of values present in another array.

That is, I have these arrays:

array1 = [1,3]
array2 = [1,2,3,4,5]

and I would check if values in array1 are all present in the array2. I should return true if at least one of array1 is different from values in array2

How can I code that in a Ruby "good" way?

P.S.: I read this solution, but it is for Java's arrays.

Hubert Kario
  • 21,314
  • 3
  • 24
  • 44
Backo
  • 18,291
  • 27
  • 103
  • 170
  • 3
    possible duplicate of [Ruby: Array contained in Array, any order](http://stackoverflow.com/questions/3897525/ruby-array-contained-in-array-any-order) – Don Roby Jul 02 '11 at 19:47

4 Answers4

10

The easiest thing would be to do a set intersection and see what you get from that:

intersection = array1 & array2
if intersection.length == array1.length
    # Everything in array1 is in array2
end

That would, of course, fail if array1 had duplicates as the intersection will automatically compress those. But we have uniq to take care of that:

intersection = array1 & array2
if intersection.length == array1.uniq.length
    # Everything in array1 is in array2
end

If you're expecting duplicates in your arrays then you'd be better off working with instances of Set rather than arrays:

require 'set'
s1 = Set.new(array1)
s2 = Set.new(array2)

if((s1 & s2) == s1)
    # Everything in array1 is in array2
end

Or use subset? to better match your intentions:

if(s1.subset?(s2))
    # Everything in array1 is in array2
end

Using sets will take care of your duplicate issues with less noise than having to use uniq all the time. There would, of course, be a bit of extra overhead but you should optimize for clarity before performance (make it work then make it fast only if it is too slow).

mu is too short
  • 426,620
  • 70
  • 833
  • 800
0

Late to the game.. but

(array2 & array1) === array1

That seems to work..

array1.present? && (array2 & array1) === array1

if you want to return true if the array has data.

I took a stab at the === operator, as it works in rspec.

baash05
  • 4,394
  • 11
  • 59
  • 97
0
includes = true

array1.each do |elem|
  if !array2.include?(elem)
    includes = false
  end
end

And you'll have in includes variable what you need

Tudor Constantin
  • 26,330
  • 7
  • 49
  • 72
-1

This can work

newarray = array1 & array2
harungo
  • 219
  • 2
  • 11