动态解构 Ruby 块参数

5
最近一篇关于Ruby解构的好文章将解构定义为能够将一组变量绑定到相应的一组值上,无论在何处,你都可以将其绑定到单个变量的值,并且举了一个块解构的例子。 文章链接
triples = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

triples.each { |(first, second, third)| puts second } =>#[2, 5, 8]

在这种情况下,我们知道主数组中元素的数量,因此当我们提供参数first,second,third时,我们可以得到相应的结果。那么如果我们有一个数组大小在运行时确定的数组呢?

triples = [[1, 2, 3], [4, 5, 6], [7, 8, 9],...,[]]

我们希望获得每个子数组的第一个条目的元素?
triples.each { |(first, second, third,...,n)| puts first }

如何动态创建本地变量 (first, second, third,...,n) 是最佳的方式?


但是为什么需要动态创建变量呢? - Geo
因为我想获取每个子数组的第n个元素。例如,假设是第20个。 - eastafri
因为我想要获取每个子数组的第n个索引处的元素。假设子数组包含超过31个元素,则获取每个子数组的第31个索引处的元素。 - eastafri
2
如果你不解构它们,你会得到一个数组。我看不出有什么情况需要将它们解构。 - Geo
2个回答

8
在您的情况下,您将使用扩展运算符来收集除第一个值以外的所有内容:
triples.each { |first, *rest| puts first }
#-----------------------^splat
< p > *rest 符号只是将剩余的所有内容收集到一个名为 rest 的数组中。

通常情况下,创建任意数量的本地变量(second, third, ..., nth)没有太多意义,因为您无法对它们执行任何操作;您可能会编写一些复杂的 eval 函数,但我们已经有了一个很好的、功能齐全的 Array 类,所以为什么要费心呢?


我想获取每个子数组的第n个索引元素,该怎么做? - eastafri
1
@eastafri:然后你可以使用 each {|x| ... } 并说 x[n-1]rest[n-2],如果你有 |first, *rest||k,v| 的“解构”语法只是一个方便的简写,用于当你知道你正在处理多少个元素以及像 a, b = [11, 23] 这样的情况,如果你不知道有多少个元素,则使用数组并询问它的大小。 - mu is too short

2

如果这是一个数组的数组:

triples = [[1, 2, 3], [4, 5, 6], [7, 8, 9],...,[]]

如果我们想要迭代三元组,那么这将起作用,因为内部数组只有3个元素。

triples.each { |first, second, third| puts first }

或者,你的意思是打错了吗?
new_triples = [[1, 2, 3,...,n], [4, 5, 6,...,n], [7, 8, 9,...,n],...,[]]

在这种情况下,我会采用上面“mu”的建议。
new_triples.each { |first, *rest| puts first }

希望我理解您的意图,如果有误请见谅。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接