newsn31
newsn31

Reputation: 217

How to find if one array is a subset of another array in Ruby?

Preferably in Ruby

I need a way to determine if one array is a "subarray" of another array when order matters

For instance,

a = ["1", "4", "5", "7", "10"]
b = ["1", "4", "5"]
c = ["1", "5", "4"]
d = ["1", "5", "10"]

a includes b = true
a includes c = false
a include d = false

Thanks in advance.

Upvotes: 1

Views: 1246

Answers (4)

Sagar Pandya
Sagar Pandya

Reputation: 9497

You could join the elements with an arbitrary character then compare strings:

a.join(' ').match?(array.join(' '))

This works for the test cases you have provided:

a.join(' ').match?(b.join(' '))                                                                                                                     
 #=> true
a.join(' ').match?(c.join(' '))                                                                                                                     
 #=> false
a.join(' ').match?(d.join(' '))                                                                                                                   
 #=> false

But this is not a general solution and will fail on varying types of arrays (see comments for further discussion).

Upvotes: 0

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 121000

[b, c, d].map do |arr|
  a.each_cons(arr.length).any?(&arr.method(:==))
end
#⇒ [true, false, false]

This is definitely not the most performant solution, but for not huge arrays is works and, which is important, is readable.

Enumerable#each_cons.

Upvotes: 4

iGian
iGian

Reputation: 11193

class Array
  def includes(array)
    return false if array.size > self.size
    indexes = []
    self.each_with_index {|e, i| indexes << i if e == array[0]}
    p indexes
    indexes.each do |i|
      return true if self[i..i+array.size-1] == array
    end
    return false
  end
end

p a.includes b
p a.includes c
p a.includes d

Or less phpish :)

class Array
  def includes(array)
    return false if array.size > self.size
    indexes = each.with_index.select { |e, i| e == array[0] }.map(&:last)
    indexes.each {|i| self[i..i+array.size-1] == array ? (return true) : (return false)}
  end
end

p a.includes b
p a.includes c
p a.includes d

Upvotes: 0

lacostenycoder
lacostenycoder

Reputation: 11226

a = ["1", "4", "5", "7", "10"]
b = ["1", "4", "5"]
c = ["1", "5", "4"]
d = ["1", "5", "10"]


def sub_set?(arr_a, arr_b)
  arr_a.select.with_index do |a, index|
    arr_b[index] == a
  end == arr_b
end

puts "testing sub_set #{a.inspect} and #{c.inspect}"
puts sub_set?(a,c).inspect

Upvotes: 0

Related Questions