Creating hashes with duplicate keys

I want to simplify this hash creation:
g = { 1 => “test”, 2 => “test”, }

I have a particularly complicated hash that I’m generating. It can
have very large values.

Right now, I duplicate values with something like this:

c = { 1 => “one”, }
d = { 2 => c[1], }
c.merge!(d)

however, I don’t like the way my code looks… I want to be able to
specify the duplication within the hash generation.

Is this possible?

On 28/07/06, Sy Ali [email protected] wrote:

c.merge!(d)

however, I don’t like the way my code looks… I want to be able to
specify the duplication within the hash generation.

Is this possible?

Something like this?
irb(main):001:0> c={}
=> {}
irb(main):002:0> c[1] = “one”
=> “one”
irb(main):003:0> c[2] = c[1]
=> “one”
irb(main):004:0> c[1].object_id == c[2].object_id
=> true

Farrel

On 7/28/06, Sy Ali [email protected] wrote:

d = { 2 => c[1], }
c.merge!(d)

however, I don’t like the way my code looks… I want to be able to
specify the duplication within the hash generation.

Is this possible?

Hmm I am not completely sure what you want achieve.

In the following implementations there are two possible Approaches, the
class YourHash
implements domaindependent key duplication. Iow YourHash is a mapping
from
one Domain to another and both are distinct, thus if the mapping value
is in
the mapped Domain it is just replaced by the mapping value. Ahem that
does
not read well.
I mean:
Keys and values are distinct and thus if a value is already a key it is
replaced by its value.

The second approach is to monkeypatch Hash to add a duplicate method,
allowing you
to define as many “synonyms” or “aliases” for one key.

Hope that helps

Robert
------------------------------------------------- 8<

521/21 > cat hash.rb && ./hash.rb
#!/usr/bin/env ruby

class YourHash < Hash
def []=(key, value)
if has_key?( value ) then
super(key, self[value])
else
super(key, value)
end
end
end

class Hash
def duplicate(key, *tokeys)
value = self[key]
tokeys.each do
|new_key|
self[new_key] = value
end
end
end

h = YourHash.new
h[:a]=1
h[:b]=:a

p h

h = Hash.new
h[:a]=1
h.duplicate( :a, :b, :c )
p h
--------------> OUTPUT <------------------
{:a=>1, :b=>1}
{:c=>1, :a=>1, :b=>1}


Deux choses sont infinies : l’univers et la bêtise humaine ; en ce qui
concerne l’univers, je n’en ai pas acquis la certitude absolue.

  • Albert Einstein

Sy Ali wrote:

c.merge!(d)

however, I don’t like the way my code looks… I want to be able to
specify the duplication within the hash generation.

Is this possible?

This will work:

hsh = Hash.new{|h, k| h[k] = (k == 1 ? “one” : h[k - 1])}

Note that all the values will be the same – the same object! If you
want duplicates, do this instead:

hsh = Hash.new{|h, k| h[k] = (k == 1 ? “one” : h[k - 1].dup)}

Just ask if there are parts of the snippet you don’t understand.

Cheers,
Daniel

fr Sy:

I want to simplify this hash creation:

g = { 1 => “test”, 2 => “test”, }

however, I don’t like the way my code looks… I want to be able to

specify the duplication within the hash generation.

not sure if this simple idea will help, but,

irb(main):055:0> class Hash
irb(main):056:1> def init2 range
irb(main):057:2> range.each{|c| self[c]=self.default}
irb(main):058:2> end
irb(main):059:1> end
=> nil
irb(main):060:0> h=Hash.new
=> {}
irb(main):065:0> h.default = “test”
=> “test”
irb(main):066:0> h.init2 1…8
=> 1…8
irb(main):067:0> h
=> {5=>“test”, 6=>“test”, 1=>“test”, 7=>“test”, 2=>“test”, 8=>“test”,
3=>“test”, 4=>“test”}
irb(main):068:0> h.default = “testing again”
=> “testing again”
irb(main):069:0> h.init2 6…10
=> 6…10
irb(main):070:0> h
=> {5=>“test”, 6=>“testing again”, 1=>“test”, 7=>“testing again”,
2=>“test”, 8=>“testing again”, 3=>“test”, 9=>“testing again”, 4=>“test”,
10=>“testing again”}
irb(main):071:0>

kind regards -botp

On Fri, 28 Jul 2006, Sy Ali wrote:

c.merge!(d)

however, I don’t like the way my code looks… I want to be able to
specify the duplication within the hash generation.

Is this possible?

use rbtree (from the raa)

harp:~ > cat a.rb
require ‘rbtree’

rb = RBTree.new

rb[1] = ‘test’
rb[2] = ‘test’

rb.each{|k,v| p [k,v]}

harp:~ > ruby a.rb
[1, “test”]
[2, “test”]

regards.

-a

On Fri, 28 Jul 2006 [email protected] wrote:

rb.each{|k,v| p [k,v]}

harp:~ > ruby a.rb
[1, “test”]
[2, “test”]

yikes - hit send too soon, here ya go:

harp:~ > cat a.rb
require ‘rbtree’

rb = MultiRBTree.new

rb[1] = ‘test’
rb[1] = ‘test’

rb.each{|k,v| p [k,v]}

p rb.to_a
p rb[1]

harp:~ > ruby a.rb
[1, “test”]
[1, “test”]
[[1, “test”], [1, “test”]]
“test”

-a