在Ruby中,获取数组中最大值索引的最简洁方法是什么?

Car*_*and 52 ruby arrays indexing max

如果a是数组,我想要a.index(a.max),但更像Ruby的东西.这应该是显而易见的,但我无法在其他地方找到答案.显然,我是Ruby的新手.

Chu*_*uck 109

对于Ruby 1.8.7或更高版本:

a.each_with_index.max[1]
Run Code Online (Sandbox Code Playgroud)

它做了一次迭代.不完全是最具语义性的东西,但是如果你发现自己做了很多,我会把它包装在一个index_of_max方法中.

  • 没有块的`each_with_index`返回一个给出项及其索引的枚举器.然后我们将`max`发送给这个枚举器,它在项目索引对上执行标准的`max`算法.实现`Array.<=>`以便第一个项确定排序(除非有一个平局,在这种情况下比较第二个,依此类推),所以这与在数组上执行`max`基本相同价值观本身.然后为了获得索引,我们要求结果的第二项(因为我们从`each_with_index`获得了一系列`[value,index]`对). (25认同)
  • @bergyman它不仅仅比较第一个元素.它开始与第一个元素进行比较,但如果第一个元素相等,它将继续到后续元素.因此,如果数组中有多个最大元素,则此解决方案将提供最后一个元素. (6认同)
  • 我在许多卫星之后回到这个问题,并注意到当数组'a`包含多个最大值时,`a.index(a.max)`将返回第一个的索引和'a.each_with_index.max [1]`将返回最后一个的索引,因此选择使用哪个可能取决于上下文. (4认同)
  • Chuck,我知道这个方法,但认为 Ruby 有一种方法只返回索引。(对于任何其他 Ruby 新手,a.each_with_index.max 返回数组 [最大值,最大值的索引],因此 Chuck 只是取出第二个元素。) (2认同)

eas*_*fri 14

在ruby 1.9.2中,我可以这样做;

arr = [4, 23, 56, 7]
arr.rindex(arr.max)  #=> 2
Run Code Online (Sandbox Code Playgroud)

  • 这基本上是不需要的原始解决方案的更糟版本。 (3认同)

Aru*_*hit 8

以下是我正在考虑回答这个问题:

a = (1..12).to_a.shuffle
# => [8, 11, 9, 4, 10, 7, 3, 6, 5, 12, 1, 2]
a.each_index.max_by { |i| a[i] }
# => 9
Run Code Online (Sandbox Code Playgroud)


Ale*_*emi 6

只是想注意此处某些解决方案的行为和性能差异。重复max 元素的“打破平局”行为:

a = [3,1,2,3]
a.each_with_index.max[1]
# => 3
a.index(a.max)
# => 0
Run Code Online (Sandbox Code Playgroud)

出于好奇,我将它们都运行了Benchmark.bm(对于a上述):

user     system      total        real
each_with_index.max  0.000000   0.000000   0.000000 (  0.000011)
index.max  0.000000   0.000000   0.000000 (  0.000003)
Run Code Online (Sandbox Code Playgroud)

然后我生成了一个新aArray.new(10_000_000) { Random.rand }并重新运行测试:

user     system      total        real
each_with_index.max
  2.790000   0.000000   2.790000 (  2.792399)
index.max  0.470000   0.000000   0.470000 (  0.467348)
Run Code Online (Sandbox Code Playgroud)

这让我觉得除非你特别需要选择更高的索引最大值,否则a.index(a.max)是更好的选择。