1

I have a Ruby array whose elements alternate between Strings and Hashes. For example-

["1234", Hash#1, "5678", Hash#2]

I would like to create a nested hash structure from this. So,

hash["1234"]["key in hash#1"] = value
hash["5678"]["key in hash#2"] = value

Does anyone have/now a nice way of doing this? Thank you.

3
  • 2
    It's not entirely clear what you want here. Are you wanting to take every 2nd element from the array (which should be a hash) and create a key using the previous item in the array with a hash value that you create based on the existing keys in the original hash (2nd item in the array)? Commented May 22, 2012 at 15:42
  • 1
    the hashes may have more than one key/value, where would they go? try to use valid Ruby in the examples. It's easier if you say: 1) I have this array (real array) and 2) I want this result, and 3) That's what I've tried so far. Commented May 22, 2012 at 15:49
  • 1
    I've downvoted your question because it is unclear. If you edit your question to clarify what real data might look like, and what you want to occur with that data, I will happily reverse my vote. Commented May 22, 2012 at 15:49

4 Answers 4

7

Simply use

hsh = Hash[*arr] #suppose arr is the array you have

It will slice 2 at a time and convert into hash.

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

1 Comment

You need Hash[*arr] but +1 for an otherwise excellent point!
3

I don't think there is a method on array to do this directly. The following code works and is quite easy to read.

hsh = {}

ary.each_slice(2) do |a, b|
  hsh[a] = b
end

# Now `hsh` is as you want it to be

1 Comment

Simpler: hsh = Hash[ ary.each_slice(2).to_a ] (see my answer).
1

Guessing at what you want, since "key in hash#1" is not clear at all, nor have you defined what hash or value should be:

value = 42

h1 = {a:1}
h2 = {b:2}
a = ["1234",h1,"5678",h2]
a.each_slice(2).each{ |str,h| h[str] = value }
p h1, #=> {:a=>1, "1234"=>42}
  h2  #=> {:b=>2, "5678"=>42}

Alternatively, perhaps you mean this:

h1 = {a:1}
h2 = {b:2}
a = ["1234",h1,"5678",h2]

hash = Hash[ a.each_slice(2).to_a ]
p hash             #=> {"1234"=>{:a=>1}, "5678"=>{:b=>2}}
p hash["1234"][:a] #=> 1

Comments

1

let's guess, using facets just for fun:

require 'facets'
xs = ["1234", {:a => 1, :b => 2}, "5678", {:c => 3}]
xs.each_slice(2).mash.to_h
#=> {"1234"=>{:a=>1, :b=>2}, "5678"=>{:c=>3}}

3 Comments

Already covered by ksol's answer (in a less-efficient form) and my answer (directly).
Well, there's nothing wrong with drawing from another answer to make the best possible answer. (I'm saying explicitly that you should add the Hash[] version to your answer, especially if you get the accept.) Previously your answer was just duplicative, but now it's +1able :)
@Phrogz: When I was writing it I only saw ksol's answer. And sure I don't like eachs to build a hash :-) thanks for the +1 in any case.

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.