Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.ruby > #2715 > unrolled thread
| Started by | David Sprague <david.sprague@gmail.com> |
|---|---|
| First post | 2011-04-12 20:06 -0500 |
| Last post | 2011-04-17 16:37 +0000 |
| Articles | 7 — 6 participants |
Back to article view | Back to comp.lang.ruby
hash of arrays David Sprague <david.sprague@gmail.com> - 2011-04-12 20:06 -0500
Re: hash of arrays Roger Braun <roger@rogerbraun.net> - 2011-04-12 20:27 -0500
Re: hash of arrays Roger Braun <roger@rogerbraun.net> - 2011-04-12 20:57 -0500
Re: hash of arrays Tom Reilly <w3gat@nwlagardener.org> - 2011-04-12 20:52 -0500
Re: hash of arrays jake kaiden <jakekaiden@yahoo.com> - 2011-04-12 22:05 -0500
Re: hash of arrays botp <botpena@gmail.com> - 2011-04-12 22:05 -0500
Re: hash of arrays "WJ" <w_a_x_man@yahoo.com> - 2011-04-17 16:37 +0000
| From | David Sprague <david.sprague@gmail.com> |
|---|---|
| Date | 2011-04-12 20:06 -0500 |
| Subject | hash of arrays |
| Message-ID | <17ed4aba89dcdda100deb6592ec4f9f5@ruby-forum.com> |
I'm wrote this code to bin a list of words by word-length: dict = Hash.new([]) dict_file.each do |line| line.chomp!() dict[line.length] << line end expecting that I could avoid testing each time whether this was a new entry in the hash or not by just appending to the default, an empty array, if it is new. What happens is that the *same* array is assigned as the default value to all new entries so that all the hash entries finish with the same array of values. is there away to void having to write something like: if dict.key?(line.length) dict[line.length] << line else dict[line.length] = line end or the ternary equivalent in the inner loop? thanks, Dave -- Posted via http://www.ruby-forum.com/.
[toc] | [next] | [standalone]
| From | Roger Braun <roger@rogerbraun.net> |
|---|---|
| Date | 2011-04-12 20:27 -0500 |
| Message-ID | <BANLkTinGihzXN6fYnNdyhrRMCHEqLD2UKA@mail.gmail.com> |
| In reply to | #2715 |
Hi David
2011/4/13 David Sprague <david.sprague@gmail.com>:
> I'm wrote this code to bin a list of words by word-length:
>
> dict = Hash.new([])
>
> dict_file.each do |line|
> line.chomp!()
> dict[line.length] << line
> end
>
> expecting that I could avoid testing each time whether this was a new
> entry in the hash or not by just appending to the default, an empty
> array,
> if it is new.
See http://ruby-doc.org/core/classes/Hash.html#M000718.
>
> What happens is that the *same* array is assigned as the default value
> to all new entries so that all the hash entries finish with the same
> array of values.
>
> is there away to void having to write something like:
>
> if dict.key?(line.length)
> dict[line.length] << line
> else
> dict[line.length] = line
> end
dict = Hash.new{Array.new} should work.
--
Roger Braun
rbraun.net | humoralpathologie.de
[toc] | [prev] | [next] | [standalone]
| From | Roger Braun <roger@rogerbraun.net> |
|---|---|
| Date | 2011-04-12 20:57 -0500 |
| Message-ID | <BANLkTimNPZHfpo+o0X=JUwoM5hvxhy63sQ@mail.gmail.com> |
| In reply to | #2718 |
<snip>
>> is there away to void having to write something like:
>>
>> if dict.key?(line.length)
>> dict[line.length] << line
>> else
>> dict[line.length] = line
>> end
>
> dict = Hash.new{Array.new} should work.
Sorry, I meant Hash.new{|hash,key| hash[key] = []}
--
Roger Braun
rbraun.net | humoralpathologie.de
[toc] | [prev] | [next] | [standalone]
| From | Tom Reilly <w3gat@nwlagardener.org> |
|---|---|
| Date | 2011-04-12 20:52 -0500 |
| Message-ID | <4DA501E3.3060103@nwlagardener.org> |
| In reply to | #2715 |
Define hash of hashes this way
#Using a default hash.
foo = Hash.new { |hash, key| hash[key] = Hash.new }
foo["a"][1] = "one"
foo["a"][2] = "a two"
foo["b"][3] = "b three"
foo["a"][4] = "b four"
p foo["a"][1]
p foo["a"][4]
p foo["a"].size
foo["a"].each {|x,y| p "#{x} #{y}"}
David Sprague wrote:
> I'm wrote this code to bin a list of words by word-length:
>
> dict = Hash.new([])
>
> dict_file.each do |line|
> line.chomp!()
> dict[line.length]<< line
> end
>
> expecting that I could avoid testing each time whether this was a new
> entry in the hash or not by just appending to the default, an empty
> array,
> if it is new.
>
> What happens is that the *same* array is assigned as the default value
> to all new entries so that all the hash entries finish with the same
> array of values.
>
> is there away to void having to write something like:
>
> if dict.key?(line.length)
> dict[line.length]<< line
> else
> dict[line.length] = line
> end
>
> or the ternary equivalent in the inner loop?
>
> thanks,
>
> Dave
>
>
[toc] | [prev] | [next] | [standalone]
| From | jake kaiden <jakekaiden@yahoo.com> |
|---|---|
| Date | 2011-04-12 22:05 -0500 |
| Message-ID | <0f5f3ec73bfb62bbcb3e566d55e16e48@ruby-forum.com> |
| In reply to | #2715 |
David Sprague wrote in post #992397:
> I'm wrote this code to bin a list of words by word-length:
hi david,
if you're just trying to group words by their length, i'm not sure why
you need a hash of arrays, a simple hash would do...
list = %W[a cd def ghi jklm]
hash = {}
list.collect{|entry| hash[entry.length] = entry}
p hash
=> {1=>"a", 2=>"cd", 3=>"ghi", 4=>"jklm"}
the problem here is that any words of the same length would result in
only one key (the last one) having the value of the word. you could
just switch, and use the word as the key, and the length as the value...
list.collect{|entry| hash[entry] = entry.length}
=> {"cd"=>2, "a"=>1, "jklm"=>4, "def"=>3, "ghi"=>3}
but of course if you repeat words, you'll have the same problem. the
quickest (and probably dumbest) solution i can think of is adding some
kind of "unique id" to each key, so that they don't get lost -
list = %W[a cd def ghi jklm]
hash = {}
uniqueID = 0
x = 0
while x < list.length
hash ["#{list[x].length}.#{uniqueID}"] = list[x]
x += 1
uniqueID += 1
end
hash.sort.each{|k, v| p "#{k}, #{v}"}
=>"1.0, a"
"2.1, cd"
"3.2, def"
"3.3, ghi"
"4.4, jklm"
you could then call a String#split (or something better and easier,
i'm winging it here,) on the keys, to get all the words that are 3
letters long, etc...
hashes of arrays certainly are cool though, and it might be fun to
play with them...
foo = Hash.new{|key, value| key[value] = []}
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]
| From | botp <botpena@gmail.com> |
|---|---|
| Date | 2011-04-12 22:05 -0500 |
| Message-ID | <BANLkTikrMmnVqdPx3ft8Ew1wMhxDa8MPaA@mail.gmail.com> |
| In reply to | #2715 |
On Wed, Apr 13, 2011 at 9:06 AM, David Sprague <david.sprague@gmail.com> wrote:
> dict = Hash.new([])
>
> dict_file.each do |line|
> line.chomp!()
> dict[line.length] << line
> end
there are many ways.
one way eg,
dict={}
dict_file.each do |line|
line.chomp!
(dict[line.length] ||= []) << line
end
best regards -botp
[toc] | [prev] | [next] | [standalone]
| From | "WJ" <w_a_x_man@yahoo.com> |
|---|---|
| Date | 2011-04-17 16:37 +0000 |
| Message-ID | <iof4vi0r4p@enews2.newsguy.com> |
| In reply to | #2715 |
David Sprague wrote:
> I'm wrote this code to bin a list of words by word-length:
>
> dict = Hash.new([])
>
> dict_file.each do |line|
> line.chomp!()
> dict[line.length] << line
> end
words = IO.read( "data2" ).strip.split( /\s+/ )
dict = words.group_by{|w| w.size}
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.ruby
csiph-web