这是我的任务:
输入:键盘上的数字列表
输出:列表中第二小的数字及其在列表中的位置,其中1是第一个数字的位置。
到目前为止,这是我的代码:
values = []
print "Enter a number: "
a = gets.chomp.to_i
values.push(a)
print "Enter another number: "
b = gets.chomp.to_i
values.push(b)
print "Enter another number: "
c = gets.chomp.to_i
values.push(c)
print "Enter a final number: "
d = gets.chomp.to_i
values.push(d)
new_values = values.sort
second_smallest = new_values[1]
puts "Second smallest number: #{second_smallest}"
if values.include? second_smallest
print "found matching element"
end
我能够从排序后的副本中获取第二个最小的元素,然后在原始数组中检查该元素。如何获取原始数组中匹配元素的索引并将其打印给用户?
对不起,很简单,我是红宝石的新手
答案 0 :(得分:1)
def second_smallest(arr)
smallest = arr.min
arr.each_with_index.reject { |n,_| n == smallest }.min_by(&:first)
end
second_smallest [3, 1, 4, 1, 2, 3, 5] #=> [2, 4]
second_smallest [1, 1, 1] #=> nil
second_smallest [] #=> nil
在第一个示例中,第二小的数字显然是2
。
答案 1 :(得分:0)
Ruby在Enumerable
和Enumerator
上有一些方便的方法,特别是Enumerator#with_index
和Enumerable#min_by
。因此,您可以执行以下操作:
_, (value, position) = values.each.with_index(1).min_by(2) { |value, _| value }
puts "Second smallest number is #{value} found at position #{position}"
如果您不向块传递each
方法,则返回Enumerator
,它允许您链接with_index
并将其可选参数offset
与{{ 1}},因此第一个元素是索引1而不是索引0。
现在,枚举器将对1
的集合进行操作,并在其上调用[value's element, index]
,告诉它我们想要2个最小值,然后将块参数中的args拆分为min_by
和ruby的“未使用”变量value
。那么,如果我们忽略索引,为什么还要调用_
?好吧,现在with_index
返回的min_by
具有最小的2个[value's element, index]
,我们将最小的返回到“ unused”变量value's element
中,让ruby转换下一个数组,第二个最小的变量,分别放入2个变量_
和value
中,它们分别包含最小的元素和索引(我倾向于使用position表示某些东西是基于1的,而index表示它是基于0的,但这仅仅是个人怪癖)。然后,我们可以将这些显示给最终用户。
请注意,您不不想在调用此数组之前对position
数组进行排序。如果这样做,您总是会看到第二个最小的元素位于位置2。(因此,在您的示例代码中,您要使用values
不是 values
和{{ 1}}消失)
如果您需要其他变体,例如,如果您只希望第三小值,则可以使用new_values
及其返回值来做更多的事情:
new_values
除了开始时使用splat运算符min_by
以外,其他都一样,将除最后一个元素之外的所有元素都放入该“未使用”变量中。如果您想要第二个和第三个最小,可以这样做:
*_, (value, position) = values.each.with_index(1).min_by(3) { |value, _| value }
解构并存储变量*
的最后两个返回值。或者只是
*_, (second_smallest_value, second_smallest_position), (third_smallest_value, third_smallest_position) = values.each.with_index(1).min_by(3) { |value, _| value }
存储数组而不将其解构为单个变量(因为它开始变得很庞大)