我有两个数组
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_input
是Set
,而不是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
这是我转述的截图。