user7055375
user7055375

Reputation:

How do I find the index of any element from an array within another array?

I have an array:

["a", "b", "c", "d"]

How do I figure out the index of the first element of the above array to occur within a second array:

["next", "last", "d", "hello", "a"]

The index of the first element from the first array to occur within the above array would be 2; "d" belongs to the first array and occurs at position 2.

Upvotes: 3

Views: 871

Answers (3)

pSkarl
pSkarl

Reputation: 354

This approach, wrapped in a method, returns an array containing all indexes of common elements between two arrays.

def find_positions(original_array, look_up_array)
  positions_array = []
  original_array.each do |x|
    if look_up_array.index(x) != nil
      positions_array << look_up_array.index(x)
    end
  end
  positions_array
  # positions_array.first => for the first matched element
end

If you want only the first matched element you could return positions_array.first but this way you'll not avoid the extra lookups.

PS: you could also use #collect and avoid the extra array (positions_array)

Upvotes: 0

David Gross
David Gross

Reputation: 1873

You can iterate through the array you want to be compared and use .select or .find iterator method. .find will select the first element match in the arrays while .select will match all elements in the arrays. If you want to add the index in the selection you can add .each_with_index. '.index(a)' returns the element if present else it will return nil.

alphabet = %w(a b c d)
%w(next last d hello a).each_with_index.find {|a, _index| alphabet.index(a) }
 => ["d", 2]
%w(next last d hello a).each_with_index.select {|a, _index| alphabet.index(a) }[0]
 => ["d", 2]
# if you just need the index of the first match
%w(next last d hello a).index {|a| alphabet.index(a) }
 => 2 

Upvotes: -1

tadman
tadman

Reputation: 211720

There's a couple of ways to do this, but the naive approach might work well enough to get going:

tests = ["a", "b", "c", "d"]
in_array = ["next", "last", "d", "hello", "a"]

in_array.each_with_index.find do |e, i|
  tests.include?(e)
end
# => ["d", 2]

You can speed this up by making tests a Set which avoids a lot of O(N) lookups:

tests = Set.new([ ... ])

The same code will work with include? but that's now much faster on longer lists.

Upvotes: 4

Related Questions