在Ruby中,如何找到一个元素数组的索引?

时间:2021-10-23 12:36:39

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

在Ruby 2.4中,如何找到另一个数组中数组元素的最早索引?也就是说,如果数组中的任何元素出现在另一个数组中,我想要得到第一个索引。我以为find_index可以,但是

2.4.0 :004 > a = ["a", "b", "c"]
 => ["a", "b", "c"]
2.4.0 :005 > a.find_index("a")
 => 0
2.4.0 :006 > 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".

在上面的示例中,我希望看到输出“1”,因为元素“b”出现在数组“a”中的索引1处。

4 个解决方案

#1


2  

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

find_index使用一个元素。你可以用类似的方法求出最小值

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

#2


5  

You can use Array#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.

如果给定的是一个块而不是一个参数,则返回第一个对象的索引,该块为该对象返回true。如果没有找到匹配项,返回nil。


As Cary pointed out in his comment it is not the most performant algorithm to compare all elements in a against all element 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 up front, but makes the comparison in the block much faster (overall O(n+m)):

正如Cary在他的评论中指出的那样,将a中的所有元素与['b', 'c']中的所有元素进行比较(这将导致O(n*m))并不是性能最好的算法。根据两个数组的大小,是否可以先构建一个更有效的数据结构。使用一个集合而不是一个数组在创建前面的设置中有一些成本,但是在块中进行比较的速度要快得多(整体O(n+m)):

require 'set'

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

#3


0  

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

您可以使用find_index并从数组中传递所需的值:

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:

您可以使用map来获取数组中的每个元素,然后获取每个元素对应的索引:

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:

另一种可能的处理方法是使用可枚举的#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:

如果您想使用[a]、"b"、"c"]数组检查[b"、"b"、"c"中的每个元素的索引,您可以映射第一个元素,得到数组的值,然后使用a、b、c检查这些索引:

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

You can also see Array#index and Enumerable#find_index.

您还可以看到数组#index和可枚举的#find_index。

#4


0  

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.

可以在数组a中找到数组b的所有元素的索引,找到最小索引,找到数组a中第一个元素出现的索引。

Something like below:

类似下图:

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

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

#1


2  

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

find_index使用一个元素。你可以用类似的方法求出最小值

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

#2


5  

You can use Array#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.

如果给定的是一个块而不是一个参数,则返回第一个对象的索引,该块为该对象返回true。如果没有找到匹配项,返回nil。


As Cary pointed out in his comment it is not the most performant algorithm to compare all elements in a against all element 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 up front, but makes the comparison in the block much faster (overall O(n+m)):

正如Cary在他的评论中指出的那样,将a中的所有元素与['b', 'c']中的所有元素进行比较(这将导致O(n*m))并不是性能最好的算法。根据两个数组的大小,是否可以先构建一个更有效的数据结构。使用一个集合而不是一个数组在创建前面的设置中有一些成本,但是在块中进行比较的速度要快得多(整体O(n+m)):

require 'set'

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

#3


0  

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

您可以使用find_index并从数组中传递所需的值:

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:

您可以使用map来获取数组中的每个元素,然后获取每个元素对应的索引:

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:

另一种可能的处理方法是使用可枚举的#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:

如果您想使用[a]、"b"、"c"]数组检查[b"、"b"、"c"中的每个元素的索引,您可以映射第一个元素,得到数组的值,然后使用a、b、c检查这些索引:

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

You can also see Array#index and Enumerable#find_index.

您还可以看到数组#index和可枚举的#find_index。

#4


0  

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.

可以在数组a中找到数组b的所有元素的索引,找到最小索引,找到数组a中第一个元素出现的索引。

Something like below:

类似下图:

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

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