tags:

views:

106

answers:

6

In ruby, how do I test that one array not only has the elements of another array, but contain them in that particular order?

correct_combination = [1, 2, 3, 4, 5]
[1, 5, 8, 2, 3, 4, 5].function_name(correct_combination) # => false
[8, 10, 1, 2, 3, 4, 5, 9].function_name(correct_combination) # => true

I tried using include, but that is used to test whether [1,2,3].include?(2) is true or not.

+2  A: 

Not exactly the best solution possible, but at least it's brief

(',' + [1, 5, 8, 2, 3, 4, 5].join(',') + ',').include?(',' + correct_combination.join(',') + ',')

The best solution possible would be to employ one of string searching algorithms on array but you would have to code it yourself, I don't think there's standard solution.

vava
A: 

You could simply compare the arrays as strings:

correct_combination = [1, 2, 3, 4, 5]
yep = [8, 10, 1, 2, 3, 4, 5, 9]
nope = [1, 5, 8, 2, 3, 4, 5]
if yep.to_s.include?(correct_combination.to_s)
  puts "yep"
end
if nope.to_s.include?(correct_combination.to_s)
  puts "nope"
end
Dave Everitt
http://stackoverflow.com/questions/1553462/check-if-a-string-contains-a-certain-number/1553489#1553489 is all over again :)
vava
`yep.to_s.include?(correct_combination.to_s)` returns false, because of the closing bracket of `correct_combination`.
Andrew Grimm
+7  A: 

You can use each_cons method:

arr = [1, 2, 3, 4, 5]
[1, 5, 8, 2, 3, 4, 5].each_cons(arr.size).include? arr

In this case it will work for any elements.

Yossi
I think each_cons is only available in Ruby 1.9? But a nice solution.
Dave Everitt
It's also in 1.8.7.
Jonas Elfström
A: 

Maybe <=> is what you are looking for.

Comparison—Returns an integer (-1, 0, or +1) if this array is less than, equal to, or greater than other_array

a = [1, 2, 3, 4, 5]
b = [1, 5, 8, 2, 3, 4, 5]
c = [8, 10, 1, 2, 3, 4, 5, 9]

puts a <=> b # => -1
puts a <=> c # => -1
puts a <=> a # => 0

Update: nevermind, just noted it doesn't care about position.

puts a <=> a.reverse # => -1
ba
A: 

This is the best I could come up with. All the return calls are a bit ugly, but it should be quicker than doing a string comparison if it's large arrays.

class Array
  def same?(o)
    if self.size == o.size
      (0..self.size).each {|i| return false if self[i] != o[i] }
    else
      return false
    end

    return true
  end
end

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

puts a.same?(a.reverse) # => false
puts a.same?(a) # => true
puts a.same?(b) # => false
puts a.same?(c) # => false
ba
I see now that I misunderstood the question completely. Yossi Zach seem to be on to the correct answer with `each_cons`. :)
ba
A: 

If you want to ignore the order, (as I did when I came across this post), you could use Array.sort and <=> http://ruby-doc.org/core-1.8.7/classes/Array.html#M000316

a = [1, 2, 3, 4, 5]
b = [2, 1, 5, 4, 3]
a.sort <=> b.sort

You then need to check the output value equals 0.

Jamie Cobbett
Would this work if one array had more contents than the other?
Andrew Grimm
No, because <=> is testing for equality, and we have made it so that if the same values are in each array, they will be equal once both sorted. As the linked documentation says:Thus, two arrays are ``equal’’ according to Array#<=> if and only if they have the same length and the value of each element is equal to the value of the corresponding element in the other array.
Jamie Cobbett