我有一个数字和一个数组:
n = 4
a = [0, 1, 2, 3, 3, 4]
我希望以元素大小的相反顺序找到与n
的最大a
元素对应的索引,并且在元素大小相等时以稳定的顺序找到。预期的输出是:
[5, 3, 4, 2]
此代码:
a.each_with_index.max(n).map(&:last)
# => [5, 4, 3, 2]
给出了正确的索引,但改变了顺序。
答案 0 :(得分:5)
<强>代码强>
def max_with_order(arr, n)
arr.each_with_index.max_by(n) { |x,i| [x,-i] }.map(&:last)
end
<强>实施例强>
a = [0,1,2,3,3,4]
max_with_order(a, 1) #=> [5]
max_with_order(a, 2) #=> [5, 3]
max_with_order(a, 3) #=> [5, 3, 4]
max_with_order(a, 4) #=> [5, 3, 4, 2]
max_with_order(a, 5) #=> [5, 3, 4, 2, 1]
max_with_order(a, 6) #=> [5, 3, 4, 2, 1, 0]
<强>解释强>
对于n = 3
,步骤如下。
b = a.each_with_index
#=> #<Enumerator: [0, 1, 2, 3, 3, 4]:each_with_index>
我们可以将b
转换为数组,以查看它将生成的(六个)值并传递给该块。
b.to_a
#=> [[0, 0], [1, 1], [2, 2], [3, 3], [3, 4], [4, 5]]
继续,
c = b.max_by(n) { |x,i| [x,-i] }
#=> [[4, 5], [3, 3], [3, 4]]
c.map(&:last)
#=> [5, 3, 4]
请注意arr
的元素不一定是数字,只是可比较的。
答案 1 :(得分:4)
您可以向max
提供一个区块,以使判断更加具体,如此
a.each_with_index.max(n) do |a,b|
if a[0] == b[0] # the numbers are the same
b[1] <=> a[1] # compare the indexes in reverse
else
a[0] <=> b[0] # compare the numbers themselves
end
end.map(&:last)
#=> [5,3,4,2]
max
阻止预期可比的响应,例如-1,0,1所以在这种情况下我们只是说数字是否相同然后以相反的顺序比较索引,例如4 <=> 3 #=> -1
-1表示此值较小,因此将在3
另外要扩展@ CarySwoveland的答案(我有点嫉妒,我没想到),因为你只关心返回索引,我们可以按照以下方式实现,而不需要辅助map
a.each_index.max_by(n) { |x| [a[x],-x] }
#=> [5,3,4,2]
答案 2 :(得分:0)
@compsy你写了没有改变顺序,所以它会是:
a = [0,1,2,3,3,4]
n = a.max
i = 0
a.each do |x|
break if x == n
i += 1
end
我使用变量 i 作为索引,当 x (这是分析的值)等于 n 时,我们使用 break 停止每个方法,保留 i 的最后一个值,它对应于数组中最大值的位置。请注意, i 的值因数组中的一个自然位置而不同,这是因为在数组中第一个元素是0而不是1。
我打破 每个,因为在找到值的位置后,无需继续检查数组的所有其他值。