Creating a hash from two arrays

Hi. Can anyone help with this? I’d like to end with a hash like so:

hash = {{“A” => ‘alpha’}, {‘B’ => ‘bravo’}} etc…

I’m not sure whether I can use group_by and how to handle case
insensitity. Cheers for any help.

irb(main):001:0> s = (‘A’…‘Z’).to_a
=> [“A”, “B”, “C”, “D”, “E”, “F”, “G”, “H”, “I”, “J”, “K”, “L”, “M”,
“N”, “O”, “P”, “Q”, “R”, “S”, “T”, “U”, “V”, “W”, “X”, “Y”, “Z”]

irb(main):003:0> t = %w(alpha bravo Charlie Zebra)
=> [“alpha”, “bravo”, “Charlie”, “Zebra”]

irb(main):001:0> s = (‘A’…‘Z’).to_a
=> [“A”, “B”, “C”, “D”, “E”, “F”, “G”, “H”, “I”, “J”, “K”, “L”, “M”,
“N”, “O”, “P”, “Q”, “R”, “S”, “T”, “U”, “V”, “W”, “X”, “Y”, “Z”]

irb(main):003:0> t = %w(alpha bravo Charlie Zebra)
=> [“alpha”, “bravo”, “Charlie”, “Zebra”]
I will suggest something different based on what you wish to do. This
uses inject:
—t = %w(alpha bravo Charlie Zebra)
result = t.inject(Hash.new) do | words, word | first_letter =
word[0].upcase words[first_letter] = word wordsend—
result looks like this:
{“A”=>“alpha”, “B”=>“bravo”, “C”=>“Charlie”, “Z”=>“Zebra”}
Now, if there’s a chance that words with start with the letter A, or any
other letter might occur, I instead recommend an array based approach:
—t = %w(alpha bravo Charlie Zebra)
result = t.inject(Hash.new) do | words,word | first_letter =
word[0].upcase if words.has_key? first_letter words[first_letter] <<
word else words[first_letter] = [word] end wordsend—
result produces:
{“A”=>[“alpha”], “B”=>[“bravo”], “C”=>[“Charlie”], “Z”=>[“Zebra”]}
In both cases, the first letter is uppercased to handle being case
insensitive. Let me know if you have any questions regarding this, or if
you have a different problem you are trying to solve.
Best Regards,Chris W.

On Fri, Sep 9, 2011 at 9:51 AM, simon harrison
[email protected]wrote:

“N”, “O”, “P”, “Q”, “R”, “S”, “T”, “U”, “V”, “W”, “X”, “Y”, “Z”]

irb(main):003:0> t = %w(alpha bravo Charlie Zebra)
=> [“alpha”, “bravo”, “Charlie”, “Zebra”]


Posted via http://www.ruby-forum.com/.

Funny, I just looked this up yesterday:

irb(main):003:0> t = %w(alpha bravo Charlie Zebra)
=> [“alpha”, “bravo”, “Charlie”, “Zebra”]

My message got garbled for some reason… Here is the
gist:Character Mapping · GitHub

On Fri, Sep 9, 2011 at 5:51 PM, simon harrison
[email protected] wrote:

irb(main):003:0> t = %w(alpha bravo Charlie Zebra)
=> [“alpha”, “bravo”, “Charlie”, “Zebra”]

First, {{“A” => “alpha”}, {“B” => “bravo”}} isn’t valid syntax. You
probably meant:

{“A” => “alpha”, “B” => “bravo”, …}

?

You can indeed use group_by:

((“A”…“C”).to_a + (“a”…“c”).to_a).group_by { |e| e[0, 1].downcase }
=> {“a”=>[“A”, “a”], “b”=>[“B”, “b”], “c”=>[“C”, “c”]}

Alternatively, if you want to simply map from a[i] to b[i] in a hash,
you can use #zip, #flatten and a splat, in combination with Hash.[]:

a = %w[a b c d e]; b = (1…5)

c = a.zip(b)
=> [[“a”, 1], [“b”, 2], [“c”, 3], [“d”, 4], [“e”, 5]]

c.flatten!
=> [“a”, 1, “b”, 2, “c”, 3, “d”, 4, “e”, 5]

Hash[*c] # equivalent to Hash[“a”, 1, “b”, 2, …]
=> {“a”=>1, “b”=>2, “c”=>3, “d”=>4, “e”=>5}

Or, in one go:

Hash[*a.zip(b).flatten]
=> {“a”=>1, “b”=>2, “c”=>3, “d”=>4, “e”=>5}

Zip, flatten, splat.

This obviously won’t let you store multiple elements (“a” => [“a”,
“A”]) as in the above approach.

On Fri, Sep 9, 2011 at 6:05 PM, Chris W. [email protected] wrote:

I will suggest something different based on what you wish to do. This uses
inject:

I wouldn’t use inject ! You aren’t really reducing something down to
one element, you’re converting a mapping which exists based on an
index into an actual hash. Aside from that, the group_by is much
easier to comprehend quickly than the inject approach in your second
example.

This works in 1.9 at least.

If both arrays are the same size, you can use Array.zip and Hash[] like
this:

irb(main):001:0> alpha = (‘A’…‘Z’).to_a
=> [“A”, “B”, “C”, “D”, “E”, “F”, “G”, “H”, “I”, “J”, “K”, “L”, “M”,
“N”, “O”, “P”, “Q”, “R”, “S”, “T”, “U”, “V”, “W”, “X”, “Y”, “Z”]
irb(main):002:0> ansi = %w{Alpha Bravo Charlie Delta Echo Foxtrot Golf
Hotel India Juliet Kilo Lima Mike November Oscar Papa Quebec Romeo
Sierra Tango Uniform Victor Whiskey X-ray Yankee Zulu}
=> [“Alpha”, “Bravo”, “Charlie”, “Delta”, “Echo”, “Foxtrot”, “Golf”,
“Hotel”, “India”, “Juliet”, “Kilo”, “Lima”, “Mike”, “November”,
“Oscar”, “Papa”, “Quebec”, “Romeo”, “Sierra”, “Tango”, “Uniform”,
“Victor”, “Whiskey”, “X-ray”, “Yankee”, “Zulu”]
irb(main):003:0> alpha.size
=> 26
irb(main):004:0> ansi.size
=> 26
irb(main):005:0> alpha.zip(ansi)
=> [[“A”, “Alpha”], [“B”, “Bravo”], [“C”, “Charlie”], [“D”, “Delta”],
[“E”, “Echo”], [“F”, “Foxtrot”], [“G”, “Golf”], [“H”, “Hotel”], [“I”,
“India”], [“J”, “Juliet”], [“K”, “Kilo”], [“L”, “Lima”], [“M”,
“Mike”], [“N”, “November”], [“O”, “Oscar”], [“P”, “Papa”], [“Q”,
“Quebec”], [“R”, “Romeo”], [“S”, “Sierra”], [“T”, “Tango”], [“U”,
“Uniform”], [“V”, “Victor”], [“W”, “Whiskey”], [“X”, “X-ray”], [“Y”,
“Yankee”], [“Z”, “Zulu”]]
irb(main):006:0> zippedhash = Hash[alpha.zip(ansi)]
=> {“A”=>“Alpha”, “B”=>“Bravo”, “C”=>“Charlie”, “D”=>“Delta”,
“E”=>“Echo”, “F”=>“Foxtrot”, “G”=>“Golf”, “H”=>“Hotel”, “I”=>“India”,
“J”=>“Juliet”, “K”=>“Kilo”, “L”=>“Lima”, “M”=>“Mike”, “N”=>“November”,
“O”=>“Oscar”, “P”=>“Papa”, “Q”=>“Quebec”, “R”=>“Romeo”, “S”=>“Sierra”,
“T”=>“Tango”, “U”=>“Uniform”, “V”=>“Victor”, “W”=>“Whiskey”,
“X”=>“X-ray”, “Y”=>“Yankee”, “Z”=>“Zulu”}

SUMMARY:

new_hash = Hash[array1.zip(array2)]

Quick-and-easy so long as array1 and array2 are equal length.

Aaron out.

On Fri, Sep 9, 2011 at 6:15 PM, Aaron D. Gifford [email protected]
wrote:

SUMMARY:

new_hash = Hash[array1.zip(array2)]

Ah, yes, this works without the splat, too. I seem to remember that
this doesn’t work on 1.8(.7?), which is when I learned it.

Thanks for all the help. I knew about zip but as both arrays have to
have the same number of elements it doesn’t help in this case. Two more
questions:

  1. Are there any tutorials/blog posts explaining converting arrays to
    hashes and using inject?

  2. My real aim is to move files/directories into A-Z directories. I’m
    also interested in the general principles for copying values that are
    common from different structures to another structure. Any tutorials for
    that sort of thing?

Cheers again.

Or using just the list of words and Ruby 1.9:

ansi = %w{Alpha Bravo Charlie Delta … Zulu}
zippedhash = Hash[ansi.map{|x| x[0].downcase}.zip(ansi)]

@Adam P., I think you’re right about 1.8, which is why I
prefaced my response with “This works in 1.9 at least.” chuckle

Aaron out.

Robert, I seem to remember that it was you who said you’d implemented
all the Enumerable module using inject. Any chance of having a look at
that code?

On Fri, Sep 9, 2011 at 7:24 PM, Aaron D. Gifford [email protected]
wrote:

Or using just the list of words and Ruby 1.9:

ansi = %w{Alpha Bravo Charlie Delta … Zulu}
zippedhash = Hash[ansi.map{|x| x[0].downcase}.zip(ansi)]

@Adam P., I think you’re right about 1.8, which is why I
prefaced my response with “This works in 1.9 at least.” chuckle

or - avoiding the temporary Array:

ansi = %w{Alpha Bravo Charlie Delta … Zulu}
hash = {}
ansi.each {|w| hash[w[0].upcase] = w}

Kind regards

robert

On Mon, Sep 12, 2011 at 7:05 PM, simon harrison
[email protected] wrote:

Robert, I seem to remember that it was you who said you’d implemented
all the Enumerable module using inject. Any chance of having a look at
that code?

Currently I have no idea where that code went. :slight_smile: If I dig it up I’ll
post it.

Kind regards

robert

2011/9/12 Robert K. [email protected]:

On Mon, Sep 12, 2011 at 7:05 PM, simon harrison
[email protected] wrote:

Robert, I seem to remember that it was you who said you’d implemented
all the Enumerable module using inject. Any chance of having a look at
that code?

Currently I have no idea where that code went. :slight_smile: If I dig it up I’ll post it.

Why would anyone do that is beyond me.

:frowning:

– Matma R.

2011/9/13 Bartosz Dziewoński [email protected]:

2011/9/12 Robert K. [email protected]:

On Mon, Sep 12, 2011 at 7:05 PM, simon harrison
[email protected] wrote:

Robert, I seem to remember that it was you who said you’d implemented
all the Enumerable module using inject. Any chance of having a look at
that code?

Currently I have no idea where that code went. :slight_smile: If I dig it up I’ll post
it.

Why would anyone do that is beyond me.

Well, I am trying to be kind and provide the information I have. I
cannot find anything strange about that.

Cheers

robert


remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

:wink: