循环遍历数组并比较Ruby中的连续元素

0 ruby loops

这是一个简单的 Python 程序,它输出连续元素值的变化:

amounts = [10, 9, 10, 3, 100, 100, 90, 80, 10, 30, 10]
for i in range(0, len(amounts)-1):
  if amounts[i+1] > amounts[i]:
    print("up", amounts[i+1]-amounts[i])
  elif amounts[i+1] < amounts[i]:
    print("down", amounts[i]-amounts[i+1])
  else:
    print("stay")
Run Code Online (Sandbox Code Playgroud)

以下 Ruby 代码是我第一次尝试从 Python 翻译上述内容:

amounts = [10, 9, 10, 3, 100, 100, 90, 80, 10, 30, 10]
for i in 0..(amounts.count)-1 do
  if amounts.at(i+1) > amounts.at(i)
    printf "up %d", (amounts.at(i+1)-amounts.at(i))
    if amounts.at(i+1) < amounts.at(i)
      printf "down %d", (amounts.at(i)-amounts.at(i+1))
    end
  else
    print "stay"
  end
end
Run Code Online (Sandbox Code Playgroud)

此 Ruby 代码按原样返回 NoMethodError。如果有人能启发我了解 Ruby 的神奇方式,我会很高兴。

Tom*_*ord 5

这是 python 代码到 ruby​​ 的“直接”翻译 - 请注意,语法几乎相同!(唯一的细微差别是elifvselsifprint/puts语法。)

amounts = [10, 9, 10, 3, 100, 100, 90, 80, 10, 30, 10]
for i in 0..(amounts.count)-2 do
  if amounts[i+1] > amounts[i]
    puts "up #{amounts[i+1]-amounts[i]}"
  elsif amounts[i+1] < amounts[i]
    puts "down #{amounts[i]-amounts[i+1]}"
  else
    puts "stay"
  end
end
Run Code Online (Sandbox Code Playgroud)

使用没有任何问题Array#at,但它只是Array#[]. 因此,如果您的问题是关于“翻译”代码,那么我认为为了更改而进行更改没有意义。

请注意,我还修复了您的代码的两个版本中都存在的逐一错误——您只能将其运行到len(amounts)-2,而不是len(amounts)-1,否则您将越界!

但是,这并不是真正以“红宝石方式”编写的。for循环在 ruby​​ 中很少使用,因为该语言具有其他高度表达的迭代器。这是我如何编写它,使用Enumerable#each_cons

amounts = [10, 9, 10, 3, 100, 100, 90, 80, 10, 30, 10]
amounts.each_cons(2) do |first, second|
  if first < second 
    puts "up #{second - first}"
  elsif first > second
    puts "down #{first - second}"
  else
    puts "stay"
  end
end

# Output:
down 1
up 1
down 7
up 97
stay
down 10
down 10
down 70
up 20
down 20
Run Code Online (Sandbox Code Playgroud)

这种语法的一个优点是逐一错误(就像您在 python 中遇到的那样!)实际上是不可能的,因为您只是说“循环遍历所有元素”而不必担心自己跟踪索引。

这实际上是欣赏ruby优雅的一个很好的例子,如果代码是以“ruby 方式”编写的,而不仅仅是直接翻译。