【问题标题】:Ruby: How to find the index of the minimum array element?Ruby:如何找到最小数组元素的索引?
【发布时间】:2011-06-25 06:08:33
【问题描述】:

有什么方法可以更优雅地重写它吗?我认为,这是一段糟糕的代码,应该重构。

>> a = [2, 4, 10, 1, 13]
=> [2, 4, 10, 1, 13]
>> index_of_minimal_value_in_array = a.index(a.min)
=> 3

【问题讨论】:

  • 对此我不确定。也许是我过度焦虑。
  • 我会说这是非常干净的,所以这里不需要“重构”。
  • @prostosuper:我不会删除它。这几乎是一个自我回答的问题,但尽管如此,人们试图获得数组中的最小元素索引,我发现这个问题很有帮助。因此,只需创建一个类似“显然没有比 a.index(a.min) 更好的解决方案”这样的答案并接受它:)
  • 如果数组中有多个最小值怎么办?你想要第一个、最后一个还是全部?顺便说一句,我认为这是一个有价值的问题。
  • @prostosuper:你能先说说你为什么要寻找索引吗?如果你能描述更广泛的问题,也许需要一种不同的方法。

标签: ruby arrays indexing element minimum


【解决方案1】:

我相信这只会遍历数组一次并且仍然易于阅读:

numbers = [20, 30, 40, 50, 10]           # => [20, 30, 40, 50, 10]
elem, idx = numbers.each_with_index.min  # => [10, 4]

【讨论】:

  • 简洁的解决方案。不幸的是,Array#last 让它变得很丑 (ary.each_with_index.min.last)。
  • 也许ary.each_with_index.min.second 更漂亮。
【解决方案2】:

这只会遍历数组一次,而 ary.index(ary.min) 会遍历两次:

ary.each_with_index.inject(0){ |minidx, (v,i)| v < a[minidx] ? i : minidx }

【讨论】:

  • ary.each_with_index.inject([Float::INFINITY,0]) { |(mv,mi), (v,i)| v&lt;mv ? [v,i] : [mv,mi] }
【解决方案3】:

阅读其他情况(查找所有且仅最后一个最小元素)会很有趣。

ary = [1, 2, 1]

# find all matching elements' indexes
ary.each.with_index.find_all{ |a,i| a == ary.min }.map{ |a,b| b } # => [0, 2]
ary.each.with_index.map{ |a, i| (a == ary.min) ? i : nil }.compact # => [0, 2]

# find last matching element's index
ary.rindex(ary.min) # => 2

【讨论】:

  • ary.each.with_index... 和 ary.each_with_index... 之间有什么明显区别吗?我发现 each_with_index 没有记录。但是 ary.methods.grep(/each_with_index/);是真的。
  • 它们都记录在 Enumerator 中,Array 继承自该 Enumeratoreach.with_index 获取数组并向其添加索引,从而形成数组数组,内部数组包含原始元素和索引。然后您可以将其传递给其他转换器,例如mapeach_with_index 想要遍历数组的数组。这是一个微妙的区别,但我不想要 each 循环,我想转换。
  • 问题不在于速度,而在于完成某事的替代方法。为什么选择这个?我不知道。
【解决方案4】:

我其实很喜欢@andersonvom 的回答,它只需要循环数组一次就可以得到索引。

如果你不想使用ary.each_with_index.min,你可以这样做:

ary = [2,3,4,5,1]                                             # => [2,3,4,5,1]
_, index_of_minimal_value_in_array = ary.each_with_index.min  # => [1, 4]
index_of_minimal_value_in_array                               # => 4

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-17
    • 2011-02-22
    • 2017-12-13
    • 1970-01-01
    相关资源
    最近更新 更多