Ruby-比较数组并根据条件获取索引



我有两个数组

array_input = %w[one two three two]
array_compare = %w[one two three four five]

如果值存在于输入数组中,我希望从array_compare数组中提取"最高"索引。期望的输出是2,因为three存在于输入阵列和compare阵列中。

我试过

val = nil
array_compare.reverse_each do |v|
val = v and break if array_input.include? v
end

但它不设置值。

如果我理解得当,

从array_compare数组中提取"最高"索引,如果该值存在于输入数组中

这可能是一个选项:

array_compare.map.with_index { |e, id| id if array_input.include? e }.compact.max #=> 2

如果是array_compare = %w[one two three four five three],则返回5

将用于查找的数组转换为一个集合,以加快查找速度
从搜索最大索引的数组末尾开始迭代(正如您正确地做的那样(,同时也是为了速度。从数组开始迭代并选择最大索引的解决方案通常较慢,因为在找到最后一个匹配元素之前,所有的查找都是无用的。下面的方法会在第一场成功的比赛中迅速停止
最后,更正最大索引,因为array_compare.reverse.each_with_index返回反转数组的索引
生成的代码可能比许多其他答案中的代码更长,但它既简单又快速:

require 'set'
array_input = %w[one two three two]
array_compare = %w[one two three four five]
set_input = array_input.to_set
i_max = nil
array_compare.reverse.each_with_index { |x, i| i_max = i and break if set_input.include? x }
# correct the index to count from the beginning of 
# array_compare, not from the end:
i_max = array_compare.length - i_max - 1;
puts i_max; # prints: 2

另请参阅:

Array.include?相对较慢。此外,如果您只需要一个用于查找的散列,请考虑使用一个集合:https://stackoverflow.com/a/411164/967621

更多关于数组、集合和散列(使用基准(的速度比较:ruby 中Set的优势

一个人可以写

array_compare.rindex { |e| array_input.include?(e) }
#=> 2

但这需要对CCD_ 8的每个元素(从最后一个开始(进行CCD_。以下内容更好。

array_compare.rindex((array_compare & array_input).last)
#=> 2

步骤如下。

a = array_compare & array_input
#=> ["one", "two", "three"]

请参见阵列#&。注意,";从原始数组[array_compare]中保留顺序&";。这种单程操作将非常快,因为它在C中实现。继续,

e = a.last
#=> "three" 
array_compare.rindex(e)
#=> 2

请参阅数组#rindex。

我能想到的性能最好的解决方案是:

def find_last_index(set_input, array_compare)
(array_compare.length - 1).downto(0) do |i|
return i if set_input.include?(array_compare[i])
end
end

注意,自变量set_inputSet,而不是Array。将数组转换为集合是有意义的,但前提是您希望用同一集合多次调用find_last_index。否则,将数组转换为集合(to_set(的过程将花费比使用Set#include?而不是Array#include?更多的时间。因此,如果你只想使用find_last_index一次,你不应该调用find_last_index(array_input.to_set, array_compare),而是使用这个根本不使用集合的版本:

def find_last_index(array_input, array_compare)
(array_compare.length - 1).downto(0) do |i|
return i if array_input.include?(array_compare[i])
end
end

您可能希望看到这个问题的不同解决方案的基准。

我刚刚在irb中执行了(复制和粘贴(您的代码,val是";三个";之后之后你真的检查过val吗,即

p val

这是我转述的截图。

最新更新