提问人:ZoRaN 提问时间:5/21/2023 最后编辑:ArctodusZoRaN 更新时间:5/24/2023 访问量:65
在数组迭代的特定情况下,Ruby 方式而不是 for 循环
Ruby way instead of for loop in specific case of array iteration
问:
来自其他语言,其中for循环是主要的迭代方式,我很好奇是否有更好的Ruby风格方法可以实现以下目标:
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
感谢!
提交的代码实际上有效,但是知道在 Ruby 中每个代码都在后台使用,我不确定使它更紧凑和高效的最佳方法是什么。
答:
5赞
Jörg W Mittag
5/21/2023
#1
最 Ruby 的方法可能是使用 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
例如:
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
mixin 处理。学习和理解这个 mixin 的文档对于编写好的、惯用的 Ruby 代码至关重要。
作为一个(略微夸张的)一般规则,如果你必须在 Ruby 中编写一个循环或手动摆弄索引或计数器,你很可能做错了什么。事实上,由于大多数现代编程语言都附带了强大的算法、数据结构和集合库,这不仅适用于 Ruby,而且几乎普遍适用。
评论
0赞
Cary Swoveland
5/22/2023
ZoRaN,请注意.我们可以通过将枚举器转换为数组来查看该枚举器将生成的对象: .但是 wait,是一个方法,但是,作为一个数组,只响应方法。那么这是如何工作的呢?...enum1 = q.each_slice(3) #=> #<Enumerator: [5, 1, 7, 9, 0, 3, 6, 8, 0]:each_slice(3)>
Enum1.to_a #=> [[5, 1, 7], [9, 0, 3], [6, 8, 0]]
each_slice
Enumerable
q
Array
0赞
Cary Swoveland
5/22/2023
...为了使一个类能够使用模块中定义的方法,该类(为一个)必须满足两个要求:它必须 Module#include 模块(例如,)并在返回枚举器的类上定义一个方法(即类的实例)。这是因为方法只能在作为类元素的对象上调用......Enumerable
Array
Array.include(Enumerable)
each
Enumerator
Enumerable
Enumerator
0赞
Cary Swoveland
5/22/2023
...所以实际上有一个你没有看到的步骤:(注意:),然后.许多内置类包含和定义类,(并且是另外两个)。可以采用相同的方式在自定义类中包含方法。现在。为什么?enum0 = q.each #=> #<Enumerator: [5, 1, 7, 9, 0, 3, 6, 8, 0]:each>
enum0.to_a #=> [5, 1, 7, 9, 0, 3, 6, 8, 0]
enum1 = enum0.each_slice(3) #=> #<Enumerator: #<Enumerator: [5, 1, 7, 9, 0, 3, 6, 8, 0]:each>:each_slice(3)>
Enumerable
each
Hash
Range
Enumerable
enum1.map { |arr| arr.sum } #=> [13, 12, 14]
0赞
user229044
5/21/2023
#2
如前所述,这几乎是理想的答案。each_slice
但是,如果你纯粹对遍历数字索引感兴趣,将你拥有的代码转换为更惯用的 Ruby,你可以使用一个范围并以 3 为增量向前移动:step
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]
评论