开发者

Determining whether one array contains the contents of another array in ruby

In ruby, how do I test that one array not only has the elem开发者_开发问答ents 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.


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.


I think it can be done simply.

class Array
  def contain? other; (self & other) == other end
end

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


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.


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.


This is what I came up with

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

irb(main):037:0* (a + b).sort.uniq == a.sort.uniq
=> true
irb(main):038:0> (a + c).sort.uniq == a.sort.uniq
=> false


I would like to consider continuous sequence of elements from other array in container array and present this:-- code is inspired from the Sawa's code

class Array
  def contain? other
   arr = self & other
   (arr.eql? other ) && ((self.index(arr.last) - self.index(arr.first)).eql?(other.size - 1))
  end
end

Result:--

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


I would suggestion a for loop that compares each one

@out_of_order_elements = []

for i in 0.. @array_size do
  unless submission_array[i] == @correct_combination[i]
    @out_of_order_ids.push(@submission_array[i])
  end
end 


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


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


A really quick way to do this is to simply subtract one array from the other and test for an empty array.

correct_combination = [1, 2, 3, 4, 5]
yep = [8, 10, 1, 2, 3, 4, 5, 9]
nope = [1, 8, 2, 3, 4]
if correct_combination - yep == []
  puts "yep has all the values"
end
if correct_combination - nope == []
  puts "nope has all the values"
end

This approach does not care about position so delete away!

Sorry... I missed the point to the question as well. Didn't realize you were looking for order of precedence. I came across this when looking for a solution to evaluating if one large array contained all the entries of another large array. The .all?/include? approach takes a really long time to complete. Good luck!


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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜