Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.ruby > #2796 > unrolled thread

Help on hashing multiple keys and values

Started byAdam Adam <adam_sateriale@yahoo.com>
First post2011-04-13 18:33 -0500
Last post2011-04-17 16:30 +0000
Articles 9 — 4 participants

Back to article view | Back to comp.lang.ruby


Contents

  Help on hashing multiple keys and values Adam Adam <adam_sateriale@yahoo.com> - 2011-04-13 18:33 -0500
    Re: Help on hashing multiple keys and values Clifford Heath <no@spam.please.net> - 2011-04-14 09:36 +1000
    Re: Help on hashing multiple keys and values jake kaiden <jakekaiden@yahoo.com> - 2011-04-13 18:59 -0500
    Re: Help on hashing multiple keys and values Adam Adam <adam_sateriale@yahoo.com> - 2011-04-13 19:46 -0500
      Re: Help on hashing multiple keys and values Clifford Heath <no@spam.please.net> - 2011-04-14 11:15 +1000
        Re: Help on hashing multiple keys and values jake kaiden <jakekaiden@yahoo.com> - 2011-04-13 21:05 -0500
    Re: Help on hashing multiple keys and values jake kaiden <jakekaiden@yahoo.com> - 2011-04-13 20:37 -0500
    Re: Help on hashing multiple keys and values Adam Adam <adam_sateriale@yahoo.com> - 2011-04-13 21:13 -0500
    Re: Help on hashing multiple keys and values "WJ" <w_a_x_man@yahoo.com> - 2011-04-17 16:30 +0000

#2796 — Help on hashing multiple keys and values

FromAdam Adam <adam_sateriale@yahoo.com>
Date2011-04-13 18:33 -0500
SubjectHelp on hashing multiple keys and values
Message-ID<e7079548e51ac6677d70c58dba0b2fd3@ruby-forum.com>
I'm trying to create a hash with multiple values per key from a tab
delimited file. numbers_and_colors.txt example:

1    Red
2    Blue
3    Red
2    Green

What I need is a hash that has key 2 assigned to values Blue and Green.
Running what I have below just erases the previous key, so puts
name_hash["2"] would only show Green. Ruby example:

name_hash = Hash.new
File.open("numbers_and_colors.txt").each do |file_line|
  file_line.chomp!
  line_parts = file_line.split(/\t/)
  name_hash["#{line_parts[0]}"] = "#{line_parts[1]}"

I need this in a hash, so is there another way to go about this? Thanks
in advance to any help, as you can probable tell I only started learning
Ruby recently.

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

[toc] | [next] | [standalone]


#2797

FromClifford Heath <no@spam.please.net>
Date2011-04-14 09:36 +1000
Message-ID<4da6336e$0$13391$afc38c87@news.optusnet.com.au>
In reply to#2796
On 04/14/11 09:33, Adam Adam wrote:
> I'm trying to create a hash with multiple values per key from a tab
> delimited file. numbers_and_colors.txt example:
>
> 1    Red
> 2    Blue
> 3    Red
> 2    Green
>
> What I need is a hash that has key 2 assigned to values Blue and Green.
> Running what I have below just erases the previous key, so puts
> name_hash["2"] would only show Green. Ruby example:
>
> name_hash = Hash.new
> File.open("numbers_and_colors.txt").each do |file_line|
>    file_line.chomp!
>    line_parts = file_line.split(/\t/)
>    name_hash["#{line_parts[0]}"] = "#{line_parts[1]}"
>
> I need this in a hash, so is there another way to go about this? Thanks
> in advance to any help, as you can probable tell I only started learning
> Ruby recently.

The idiom I use is to add an array to hold the values, like this:

(name_hash[key] ||= []) << value

Clifford Heath.

[toc] | [prev] | [next] | [standalone]


#2802

Fromjake kaiden <jakekaiden@yahoo.com>
Date2011-04-13 18:59 -0500
Message-ID<b832c76db626dc3107816701eed0e754@ruby-forum.com>
In reply to#2796
Adam Adam wrote in post #992620:
> I'm trying to create a hash with multiple values per key from a tab
> delimited file. numbers_and_colors.txt example:
>

>The idiom I use is to add an array to hold the values, like this:

>(name_hash[key] ||= []) << value

  hi adam -

  i do what clifford does, but since i'm thick-headed i do it a bit more
verbosely (is that a word?)...

foo = Hash.new{|key, value| key[value] = []}

  this sets up a hash, where each key's value is an array (you can also
get all crazy, and make each value a hash...)  once you've got that set,
play around with this kind of stuff...

foo ["rays"] = %W[alpha beta gamma]
foo ["planets"] = %W[mercury venus earth mars]
foo ["colors"] = %W[red orange yellow green blue indigo violet]

p foo
p foo.length
p foo ["rays"][1]
p foo ["planets"][-1]
p foo ["colors"].length


 - j

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

[toc] | [prev] | [next] | [standalone]


#2803

FromAdam Adam <adam_sateriale@yahoo.com>
Date2011-04-13 19:46 -0500
Message-ID<928715e0c5481a49668ff17d33936bbf@ruby-forum.com>
In reply to#2796
Hi Clifford and Jake,

There must be something I'm missing, when I run

name_hash = Hash.new{|key, value| key[value] = []}
File.open("numbers_and_colors.txt").each do |file_line|
  file_line.chomp!
  line_parts = file_line.split(/\t/)
  name_hash["#{line_parts[0]}"] = %W["#{line_parts[1]}"]
  puts name_hash["2"]
  end

I end up with
"Blue"
"Blue"
"Green"

I'm worried with the actual data this will be 100000 "Blue" and a 
"Green". Thanks for the help. And according to Merriam-Webster verbosely 
is indeed a word

-Adam

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

[toc] | [prev] | [next] | [standalone]


#2807

FromClifford Heath <no@spam.please.net>
Date2011-04-14 11:15 +1000
Message-ID<4da64acd$0$2446$afc38c87@news.optusnet.com.au>
In reply to#2803
On 04/14/11 10:46, Adam Adam wrote:
> There must be something I'm missing, when I run
>
> name_hash = Hash.new{|key, value| key[value] = []}
> File.open("numbers_and_colors.txt").each do |file_line|
>    file_line.chomp!
>    line_parts = file_line.split(/\t/)
>    name_hash["#{line_parts[0]}"] = %W["#{line_parts[1]}"]
>    puts name_hash["2"]
>    end
>
> I end up with
> "Blue"
> "Blue"
> "Green"
>
> I'm worried with the actual data this will be 100000 "Blue" and a
> "Green". Thanks for the help.

You shouldn't print the data until you finish processing the file.
You don't need to use "#{some-string}" to make a string into a string,
and I've no idea what you're attempting by using %W[...].
You didn't seem to understand or apply the pattern I suggested.

Basically it says: Find this array in the hash (if it doesn't exist
then initialize it  with an empty array) and append this word to the array.

Try the following program (which contains the data file), understand
it, and if there's something you don't follow, come back and ask again.
The output it gives is this:

{1=>["Red"], 2=>["Blue", "Green"], 3=>["Red"]}

If you want to arrange for the entries in each array to be unique,
you'll need to add that somehow, this doesn't do it:

name_hash = {}
DATA.each do |file_line|
   line_parts = file_line.split(/\W+/)
   (name_hash[line_parts[0].to_i] ||= []) << line_parts[1]
end

p name_hash
__END__
1    Red
2    Blue
3    Red
2    Green

[toc] | [prev] | [next] | [standalone]


#2814

Fromjake kaiden <jakekaiden@yahoo.com>
Date2011-04-13 21:05 -0500
Message-ID<6d7699c88b7487ed4b3122007b620cd0@ruby-forum.com>
In reply to#2807
Clifford Heath wrote in post #992634:

> You don't need to use "#{some-string}" to make a string into a string,

  haha, i scabbed this together from something else! there's a lot of 
unnecessary weirdness going on...  this works just as well of course:

hash [parts[0]] << parts[1]


  -j

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

[toc] | [prev] | [next] | [standalone]


#2810

Fromjake kaiden <jakekaiden@yahoo.com>
Date2011-04-13 20:37 -0500
Message-ID<6984da73c3b6617ec9cac39da9a26b37@ruby-forum.com>
In reply to#2796
hey adam -

  think i finally figured out what you were trying to do - sorry for not 
reading your first post a little more carefully...  try this:

hash = Hash.new{|key, value| key[value] = []}
file = File.open("hashtext.txt", 'r')
file.each do |line|
        line.chomp!
  parts = line.split(/\t/)
  hash ["#{parts[0]}"] << "#{parts[1]}"
end
file.close

p hash["1"]
p hash ["2"]
p hash ["3"]

=> ["red"]
   ["blue", "green"]
   ["red"]


 - j

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

[toc] | [prev] | [next] | [standalone]


#2815

FromAdam Adam <adam_sateriale@yahoo.com>
Date2011-04-13 21:13 -0500
Message-ID<031f7923ec24ddc82c89431be229caeb@ruby-forum.com>
In reply to#2796
Jake and Clifford,

Both methods work wonderfully, thanks for the help, this was bothering 
me for 2 hours. Sorry for the bother, Clifford, I tried your first 
suggestion, but I had no idea about the necessary  <<. Thanks again, 
much appreciated!

Adam

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

[toc] | [prev] | [next] | [standalone]


#3064

From"WJ" <w_a_x_man@yahoo.com>
Date2011-04-17 16:30 +0000
Message-ID<iof4ih0qu7@enews2.newsguy.com>
In reply to#2796
Adam Adam wrote:

> I'm trying to create a hash with multiple values per key from a tab
> delimited file. numbers_and_colors.txt example:
> 
> 1    Red
> 2    Blue
> 3    Red
> 2    Green
> 
> What I need is a hash that has key 2 assigned to values Blue and Green.
> Running what I have below just erases the previous key, so puts
> name_hash["2"] would only show Green. Ruby example:
> 
> name_hash = Hash.new
> File.open("numbers_and_colors.txt").each do |file_line|
>   file_line.chomp!
>   line_parts = file_line.split(/\t/)
>   name_hash["#{line_parts[0]}"] = "#{line_parts[1]}"
> 
> I need this in a hash, so is there another way to go about this? Thanks
> in advance to any help, as you can probable tell I only started learning
> Ruby recently.

name_hash = {}
name_hash.default = []
IO.foreach( "data2" ){|line|
  key, val = line.split
  name_hash[ key ] += [val]
}
p name_hash

  ==>

{"1"=>["Red"], "2"=>["Blue", "Green"], "3"=>["Red"]}

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.ruby


csiph-web