Ruby中特定情况下的数组迭代,可以使用Ruby的方式而不是for循环。

huangapple go评论79阅读模式
英文:

Ruby way instead of for loop in specific case of array iteration

问题

在其他编程语言中,for循环通常是主要的迭代方式,我想知道在Ruby中是否有更好、更符合Ruby风格的方法来实现以下代码:

q = [5, 1, 7, 9, 0, 3, 6, 8, 0]

for i in 0..q.size/3-1
  # 对 q[0+i*3] 执行一个操作
  # 对 q[1+i*3] 执行另一个操作
  # 对 q[2+i*3] 执行第三个操作
end

这个问题中提交的代码实际上可以工作,但考虑到Ruby中的for循环在内部使用each,我不确定如何以更紧凑和高效的方式实现它。

英文:

Coming from other languages where for loop is predominant way of iterating, I am curious is there a better more Ruby style way to achieve below:

q=[5,1,7,9,0,3,6,8,0]

for i in 0..q.size/3-1

  do one thing with q[0+i*3]

  do another one with q[1+i*3]

  third operation on q[2+i*3]

end

THX!

Code submitted in question actually works, but knowing that for in Ruby uses each under the hood, I am not sure what is the best way to make it more compact&efficient.

答案1

得分: 5

以下是翻译好的部分:

最常用的 Ruby 方法可能是使用 Enumerable#each_slice 来完成这个任务:

q.each_slice(3) do |first, second, third|
  # 使用 `first` 做一些操作
  # 使用 `second` 做另一些操作
  # 使用 `third` 进行第三个操作
end

例如:

q.each_slice(3) do |first, second, third|
  p({ first:, second:, third: })
end
# { first: 5, second: 1, third: 7 }
# { first: 9, second: 0, third: 3 }
# { first: 6, second: 8, third: 0 }

总的来说,在任何程序中最重要的操作之一是"遍历数据"(或更一般地说,遍历、转换、过滤、构建和折叠集合),而在 Ruby 中,这是由 Enumerable 混入处理的。研究和理解这个混入的文档对于编写良好的、符合习惯的 Ruby 代码是至关重要的。

作为一个(稍微夸张的)通则,如果你在 Ruby 中必须编写循环或手动操作索引或计数器,那么你很可能正在做一些错误的事情。实际上,对于大多数现代编程语言中提供的强大算法、数据结构和集合库来说,这不仅适用于 Ruby,而且几乎适用于所有编程语言。

英文:

The most Ruby way to do this would probably be to use Enumerable#each_slice:

q.each_slice(3) do |first, second, third|
  # do something with `first`
  # do another thing with `second`
  # third operation with `third`
end

For example:

q.each_slice(3) do |first, second, third|
  p({ first:, second:, third: })
end
# { first: 5, second: 1, third: 7 }
# { first: 9, second: 0, third: 3 }
# { first: 6, second: 8, third: 0 }

In general, one of the most important operations in any program is "iterating over stuff" (or more generally, traversing, transforming, filtering, building, and folding collections), and in Ruby, that is handled by the Enumerable mixin. Studying and understanding this mixin's documentation is crucial to writing good, idiomatic Ruby code.

As a (slightly exaggerated) general rule, if you have to write a loop or manually fiddle with indices or counters in Ruby, you are very likely doing something wrong. In fact, with the powerful algorithms, data structures, and collections libraries that are shipped with most modern programming languages, that does not just apply to Ruby but almost universally.

答案2

得分: 0

As already pointed out, each_slice is pretty much the ideal answer here.

然而,如果你只对数值索引循环感兴趣,并希望将你的代码转化为更具 Ruby 风格的写法,你可以使用一个范围和 step 来按照每次增加 3 来移动:

q=[5,1,7,9,0,3,6,8,0]

(0..q.size - 1).step(3) do |i|
  a = q[i]
  b = q[i + 1]
  c = q[i + 2]

  p [a, b, c]
end

# [5, 1, 7]
# [9, 0, 3]
# [6, 8, 0]
英文:

As already pointed out, each_slice is pretty much the ideal answer here.

However if you were purely interested in looping over the numeric indices, transforming the code you have into something more idiomatically Ruby, you might use a range and step to move forwards by in increments of 3:

q=[5,1,7,9,0,3,6,8,0]

(0..q.size - 1).step(3) do |i|
  a = q[i]
  b = q[i + 1]
  c = q[i + 2]

  p [a, b, c]
end

# [5, 1, 7]
# [9, 0, 3]
# [6, 8, 0]

huangapple
  • 本文由 发表于 2023年5月21日 19:07:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/76299586.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定