简体   繁体   中英

In Ruby how do I find the index of one of an array of elements?

In Ruby 2.4, how do I find the earliest index of an element of an array in another array? That is, if any element of an array occurs in the other array, I want to get the first index. I thought find_index might do it, but

a = ["a", "b", "c"]
# => ["a", "b", "c"]
a.find_index("a")
# => 0
a.find_index(["b", "c"])
# => nil

In the above example, I would expect to see the output "1" because the element "b" occurs at index 1 in the array "a".

find_index takes a single element. You could find the minimum by doing something like

a = ["a", "b", "c"]
to_find = ["b", "c"]
to_find.map {|i| a.find_index(i) } .compact.min # => 1

You can use find_index and pass the needed value from the array:

a = ["a", "b", "c"]
p a.find_index('a')
p a.find_index('b')
p a.find_index('c')
# => 0
# => 1
# => 2

You can use map to get every element inside your a array and then to get the index corresponding to each element:

p a.map{|e| a.find_index(e)}
# => [0, 1, 2]

Another possible way to handle it could be to use the Enumerable#each_with_index :

a.each_with_index{|e,i| puts "Element: #{e}, Index: #{i}"}
# => Element: a, Index: 0
# => Element: b, Index: 1
# => Element: c, Index: 2

If you want to check the indexes for each element in ["b", "c"] using the ["a", "b", "c"] array, you can map the first one, get the array values, and then use the a,b,c to check those indexes:

p ["b", "c"].map{|e| ["a", "b", "c"].find_index(e) }
# => [1, 2]

You can also seeArray#index and Enumerable#find_index .

You can useArray#index with a block.

a = ['a', 'b', 'c']
a.index { |x| ['b', 'c'].include?(x) }
#=> 1

Quote from the docs:

If a block is given instead of an argument, returns the index of the first object for which the block returns true. Returns nil if no match is found.


As Cary pointed out in his comment it is not the most performant algorithm to compare all elements in a against all elements in ['b', 'c'] (this would lead to O(n*m) ). Depending on the size of both arrays if might sense to build a more efficient data structure first. Using a Set instead of an Array has some cost in creating the set upfront, but makes the comparison in the block much faster (overall O(n+m) ):

require 'set'

a = ['a', 'b', 'c']
set = Set.new(['b', 'c'])
a.index { |x| set.include?(x) }
#=> 1

You could find index of all elements of array b in the array a , and find the min index to find the index at which an element from array b occurred first in array a .

Something like below:

a = ["a", "b", "c"]
b = ["b", "c"]

b.map { |x| a.find_index(x) }.min
#=> 1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM