在Ruby中找到匹配数组元素的索引

时间:2018-07-21 20:30:37

标签: arrays ruby indexing matching

这是我的任务:

输入:键盘上的数字列表

输出:列表中第二小的数字及其在列表中的位置,其中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

我能够从排序后的副本中获取第二个最小的元素,然后在原始数组中检查该元素。如何获取原始数组中匹配元素的索引并将其打印给用户?

对不起,很简单,我是红宝石的新手

2 个答案:

答案 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在EnumerableEnumerator上有一些方便的方法,特别是Enumerator#with_indexEnumerable#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 }

存储数组而不将其解构为单个变量(因为它开始变得很庞大)