6

I am currently trying to convert this ruby array:

[5, 7, 8, 1]

into this:

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

I am currently doing it like this:

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

but I'm getting the following warning:

warning: default `to_a' will be obsolete
user664833
  • 18,397
  • 19
  • 91
  • 140
jlstr
  • 2,986
  • 6
  • 43
  • 60

5 Answers5

30

The shortest and fastest solution is using Array#zip:

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

Another cute way is using transpose:

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

The most intuitive way is probably what @Thom suggests:

values.map { |e| [e] }
user664833
  • 18,397
  • 19
  • 91
  • 140
Marc-André Lafortune
  • 78,216
  • 16
  • 166
  • 166
18

In point-free style:

[5, 7, 8, 1].map(&method(:Array))
Jörg W Mittag
  • 363,080
  • 75
  • 446
  • 653
  • I always wanted to know what this syntax means: **&method** Could you explain it to me? – jlstr Aug 07 '11 at 14:17
  • 1
    @user766388: This has already been asked and answered well over a dozen times here on StackOverflow. I *really* don't feel like answering it yet *again*: [Understanding \[ClassOne, ClassTwo\].each\(&:my_method\)](http://StackOverflow.Com/q/99318/), [What does `map(&:name)` mean in Ruby?](http://StackOverflow.Com/q/1217088/), [What exactly is `&:capitalize` in Ruby?](http://StackOverflow.Com/q/1792683/), [Ruby/Ruby on Rails ampersand colon shortcut](http://StackOverflow.Com/q/1961030/), [Ruby : `&:symbol` syntax](http://StackOverflow.Com/q/2096975/), … – Jörg W Mittag Aug 07 '11 at 16:33
  • … [What is this `&:last` Ruby Construct Called?](http://StackOverflow.Com/q/2211751/), [What do you call the `&:` operator in Ruby?](http://StackOverflow.Com/q/2259775/), [What does `map(&:name)` do in this Ruby code?](http://StackOverflow.Com/q/2388337/), [What are `:+` and `&+` in ruby?](http://StackOverflow.Com/q/2697024/), [`&:views_count` in `Post.published.collect(&:views_count)`](http://StackOverflow.Com/q/3888044/), [Ruby Proc Syntax](http://StackOverflow.Com/q/4512587/), [How does “`(1..4).inject(&:+)`” work in Ruby](http://StackOverflow.Com/q/5003257/), … – Jörg W Mittag Aug 07 '11 at 16:33
  • … [What does following statement `&:property` ?](http://StackOverflow.Com/q/5620411/), [What does the `&` mean in the following ruby syntax?](http://StackOverflow.Com/q/5952175/), [Why would one use the unary operator on a property in ruby? i.e `&:first`](http://StackOverflow.Com/q/6289084/), and [how does `Array#map` have parameter to do something like this?](http://StackOverflow.Com/q/6716629/). – Jörg W Mittag Aug 07 '11 at 16:33
  • 3
    @Jorg: This is slightly different, in that we're doing `Array(5)`, not `5.Array`. I'm curious as to whether this idiom is bad for performance. – Andrew Grimm Aug 07 '11 at 23:30
  • I've decided to ask: http://stackoverflow.com/questions/6976629/is-the-methodmethod-name-idiom-bad-for-perfomance-in-ruby – Andrew Grimm Aug 07 '11 at 23:56
  • "point-free" (or "pointfree") means *without the use of variables*; pointwise (or point-wise) means *with the use variables*. #ForThoseWhoMightNotKnow – user664833 Mar 20 '21 at 20:35
12

Try this:

[5, 7, 8, 1].map {|e| [e]}
Thom Smith
  • 13,916
  • 6
  • 45
  • 91
  • AWESOME ! I didn't know I could be so direct ! – jlstr Aug 05 '11 at 21:45
  • 2
    This answer is correct, though the question should probably be phrased differently. When an array is flattened, all dimensions are resolved to just one. There's no way to know what the original arrangement was (at least I can't think of one). The question for your answer should be something like "how do I take an array and replace each element with itself in the zeroith element of an array, e.g. [0,1] becomes [[0],[1]]" or maybe something a little more clear... just saying when I saw the topic I was like 'whoa, impossible' – BF4 Aug 05 '11 at 21:49
  • 2
    @Thom: that's `map` and `collect` you are talking about, `select` is something else (also called `select` in Smalltalk, `filter` in some other languages). See for example http://smalltalk.gnu.org/blog/sblinn/list-comprehension-using-select-and-collect – Michael Kohl Aug 05 '11 at 22:12
4

There's nothing specifically wrong with what you're doing. I think they mean that to_a for a FixNum will be deprecated sometime in the future, which makes sense cause it's ambiguous what exactly to_a for a FixNum should do.

You could rewrite your line like this which would eliminate the error:

[5, 7, 8, 1].select { |element| element }.collect { |element| [element] }
Karl
  • 6,035
  • 5
  • 30
  • 39
2

You could do:

[5, 7, 8, 1].collect { |i| [i] }
Reuben Mallaby
  • 5,740
  • 4
  • 47
  • 45
  • Correct answer, but is exactly the same as Thom's, and this one is 4 seconds later. – sawa Oct 18 '11 at 17:08
  • Late comment, but then again I did upvote Thom as soon as I saw his answer. – Reuben Mallaby Oct 18 '11 at 17:13
  • Any other reasons for downvoting over two months later than an answer being accepted? – Reuben Mallaby Oct 18 '11 at 17:46
  • Voting can be done anytime. This website is intended to be reused by anyone at anytime. It is not just the original OP who would be seeking for answers. Downvoting is just a signal to future users so that they do not have to pay attention to duplicate answers. Ideally, duplicate answers should be removed. – sawa Oct 18 '11 at 18:00
  • Ideally duplicate questions should be removed. Duplicate answers should show that an answer is very good (not including answer hours+ later which would indicate a lack of reading) If there are two correct answers in close temporal proximity - upvote the first or at least provide a decent explanation of a downvote other than a four second time difference. – Reuben Mallaby Oct 18 '11 at 18:26