如何“展开”一个Ruby数组?

6

我目前正在尝试转换这个Ruby数组:

[5, 7, 8, 1]

将其转化为以下内容:

[[5], [7], [8], [1]]

我目前是这样做的:
[5, 7, 8, 1].select { |element| element }.collect { |element| element.to_a }

但是我收到了以下警告:
warning: default `to_a' will be obsolete
5个回答

30

最短且最快的解决方法是使用 Array#zip 方法:

values = [5, 7, 8, 1]
values.zip # => [[5], [7], [8], [1]]

另一种可爱的方法是使用transpose

[values].transpose # =>  [[5], [7], [8], [1]]

最直观的方式可能是@Thom建议的:

values.map { |e| [e] }

18

以无参考样式:

[5, 7, 8, 1].map(&method(:Array))

我一直想知道这个语法的意思:**&method** 您能解释一下吗? - jlstr
1
@user766388:这个问题在StackOverflow上已经被问答过十几次了。我真的不想再回答一遍了:理解[ClassOne,ClassTwo].each(&:my_method)Ruby中map(&:name)是什么意思?Ruby中的&:capitalize到底是什么?Ruby/Ruby on Rails中的:快捷方式Ruby:&:symbol语法,... - Jörg W Mittag
这是 Ruby 中的 &:last 构造叫什么?, 你如何称呼 Ruby 中的 &: 运算符?, 在 Ruby 代码 map(&:name)&:name 是干什么的?, Ruby 中的 :+&+ 是什么意思?, Post.published.collect(&:views_count) 中的 &:views_count 是什么意思?, Ruby Proc 语法, 在 Ruby 中 "(1..4).inject(&:+)" 怎么用? - Jörg W Mittag
以下代码片段&:property是什么意思?在Ruby语法中,&代表什么意思?为什么要在属性上使用一元运算符,如:firstArray#map如何有参数执行此操作? - Jörg W Mittag
3
@Jorg:这有些不同,因为我们正在使用 Array(5),而不是 5.Array。我想知道这种习惯用法是否会影响性能。 - Andrew Grimm
显示剩余2条评论

12

试试这个:

[5, 7, 8, 1].map {|e| [e]}

太棒了!我不知道我可以如此直接! - jlstr
2
这个答案是正确的,尽管问题的措辞可能需要改变。当一个数组被展平时,所有的维度都被解析成一个。没有办法知道原来的排列方式(至少我想不出来)。你回答的问题应该是像“如何将一个数组中的每个元素替换为数组的零元素,例如[0,1]变成[[0],[1]]”或者可能更清晰一些的问题...只是当我看到这个话题时,我就像“哇,不可能”。 - BF4
2
@Thom:你说的是mapcollectselect是另一回事(在Smalltalk中也称为select,在其他一些语言中称为filter)。例如,请参见http://smalltalk.gnu.org/blog/sblinn/list-comprehension-using-select-and-collect - Michael Kohl

4

你现在所做的没有明显的问题。我认为他们指的是将来可能会弃用FixNum的to_a方法,因为对于FixNum来说,to_a方法到底应该做什么不太清楚。

你可以按照以下方式重写代码行,从而消除错误:

[5, 7, 8, 1].select { |element| element }.collect { |element| [element] }

2
在这种情况下,选择操作是一个无操作;它将过滤掉nil值。 - Thom Smith
你们两个都是对的,我只是聚焦于罪魁祸首的代码,没有注意到其他的。 - Karl

2

你可以这样做:

[5, 7, 8, 1].collect { |i| [i] }

答案正确,但与Thom的完全相同,而且这个是晚了4秒。 - sawa
晚来的评论,但我一看到 Thom 的回答就点了赞。 - Reuben Mallaby
除了回答被接受超过两个月后仍然被投票降低的原因之外,还有其他原因吗? - Reuben Mallaby
投票可以随时进行。该网站旨在供任何人在任何时候重复使用。不仅原始发布者需要寻找答案。向下投票只是向未来用户发出的信号,以便他们不必关注重复的答案。理想情况下,应该删除重复的答案。 - sawa
理想情况下,应该删除重复的问题。相同的回答应该表明这个答案非常好(不包括几小时后的答案,这表明没有仔细阅读)。如果在短时间内有两个正确的答案,则应该 upvote 第一个或至少提供一个合理的解释,说明为何 downvote,而不是简单因为四秒钟的时间差异。 - Reuben Mallaby

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