0

I want to build a new array starting from a hash with the following format:

HashConst = {[120,240] => 60, [240,480]=> 30} #Constant

I need to build a new array and assign as value to a new constant with the following format:

[ [[120,240] ,1], [[240,480], 1] ]

I tried :

NewArrayConst = HashConst.keys.each{ |res| [res, 1]}

but I get instead

[ [120,240], [240,480] ]

Only solution I found is the following:

  tempVar = []
  HashConst.keys.each_with_index{ |res,idx| tempVar [idx] = [res, 1]}
  NewArrayConst = tempVar 

Anyone knows a better solution to this and can explain why I cannot get the output I expect from NewArrayConst = HashConst.keys.each{ |res| [res, 1]}. I'm using 2.2.2-p95

Edit:

As many pointed out Hash var name is wrong and misleading, I have updated that to avoid confusion

1
  • 1
    You are using the very class Hash. Redefining it is a terrible idea. Commented Jan 6, 2016 at 18:15

3 Answers 3

5

You need to use map instead of each.

Array#each method does not return the result of the code executed in the block, but instead just returns the array on which each was called, which in your case is the value of hash.keys.

Array#map collects the values returned by block into an array.

hash = {[120,240] => 60, [240,480]=> 30}
p array = hash.keys.map{ |res| [res, 1]}
#=> [[[120, 240], 1], [[240, 480], 1]]

NOTE: Do not name your variable Hash as it is already a well-known class in Ruby. Use lower case hash if need be. Also, avoid camel case for variable names such as NewArrayConst, as Ruby recommends use of snake_case for naming variables - you can refer Ruby Style Guide for more details.

Sign up to request clarification or add additional context in comments.

12 Comments

That works and thank you for the explanation. I had the wrong idea that each collected and returned the array of the executed expression
@mgtemp In what sense? I mean, if you need to create a new array, you need to create a new array.
@mgtemp compared to what? And a prooflink would be great here.
Hash is a "well-known" class? Never heard of it.
@CarySwoveland May be it should have been named Hush
|
3
h = {[120,240] => 60, [240,480]=> 30}
val = 1

h.keys.product([val])
  #=> [[[120, 240], 1], [[240, 480], 1]] 

1 Comment

This has the advantage of knowing how large the resulting structure will be "in advance", so if there are memory re-allocations involved during a map as mgtemp suggests, they may be avoidable.
-2

Have you tried Hash.to_a? Sometimes things are easier than you think.

3 Comments

Why don't you leave that up to @maza, .to_a gives us `[[[120, 240], 60], [[240, 480], 30]]' which is in the format @maza described.
But not what they're actually asking for. I don't see the confusion.
As usual, @Dave is picky-picky.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.