Odd hash behaviour

K

Kev Jackson

Hi all,

I'm still munging data and I'm struggling with Ruby's hash

For example, I want to store a value with an associated key (sounds like
a hash or associated array), but I don't want duplicates (more like a
set, in Java I'd use a HashSet to get this behaviour).

@min_pks = Hash.new()
....
# store value for key unless we already have it
@min_pks[min_key] = no unless @min_pks.has_key?(min_key)

Regardless of how I structure the above, the Hash always stores every
value, it's as if the Hash always returns a false to the query has_key?,
so it always stores a new value

The key I'm using is a 3 letter abbreviation like 'MID', 'MCY' etc, and
in the incoming data they are duplicated

I've tried googling, I've tried ri etc, and there doesn't seem to be a
Set class with Ruby (I'd rather not write my own), at least according to
the docs. I'm also aware that the problem is between the keyboard and
the chair, it's not Ruby's falut, I'm doing something dim.

Anyone help me out?

Kev
 
J

Jeremy Tregunna

Hi all,

I'm still munging data and I'm struggling with Ruby's hash

For example, I want to store a value with an associated key (sounds
like a hash or associated array), but I don't want duplicates (more
like a set, in Java I'd use a HashSet to get this behaviour).

@min_pks = Hash.new()
....
# store value for key unless we already have it
@min_pks[min_key] = no unless @min_pks.has_key?(min_key)

Regardless of how I structure the above, the Hash always stores every
value, it's as if the Hash always returns a false to the query
has_key?, so it always stores a new value

As a Hash should. Keep in mind, that if you have a key 'foo' in your
hash (let's say: @min_pks['foo'] => 42) and later you set 'foo' again
(@min_pks['foo'] = 16) then @min_pks['foo'] is now 16, and the previous
42 value is gone (read: overwrote the previous value).
The key I'm using is a 3 letter abbreviation like 'MID', 'MCY' etc,
and in the incoming data they are duplicated

I've tried googling, I've tried ri etc, and there doesn't seem to be a
Set class with Ruby (I'd rather not write my own), at least according
to the docs. I'm also aware that the problem is between the keyboard
and the chair, it's not Ruby's falut, I'm doing something dim.

Ruby comes with a Set class; you just need to require it first.
Consider:

require 'set'

your_set = Set.new ['foo', 42]

--
Jeremy Tregunna
(e-mail address removed)

"If debugging is the process of removing bugs, then programming must be
the process of putting them in." --Dykstra
 
V

Vance A Heron

Kev,
Seems to work for me ...
$ irb
irb(main):001:0> @min_pks = Hash.new()
=> {}
irb(main):002:0> key = 'MID'
=> "MID"
irb(main):003:0> @min_pks[key] = 1 unless @min_pks.has_key?(key)
=> 1
irb(main):004:0> @min_pks[key] = 2 unless @min_pks.has_key?(key)
=> nil
irb(main):005:0> p @min_pks
{"MID"=>1}
=> nil

Could you give the rest of your code and possibly some sample
data?

Vance
 
K

Kev Jackson

Vance said:
Kev,
Seems to work for me ...
$ irb
irb(main):001:0> @min_pks = Hash.new()
=> {}
irb(main):002:0> key = 'MID'
=> "MID"
irb(main):003:0> @min_pks[key] = 1 unless @min_pks.has_key?(key)
=> 1
irb(main):004:0> @min_pks[key] = 2 unless @min_pks.has_key?(key)
=> nil
irb(main):005:0> p @min_pks
{"MID"=>1}
=> nil

Could you give the rest of your code and possibly some sample
data?
Actually it was working, but when printing out the values, it prints
everything (ie including things that shouldn't have been in the Hash).
I figured it all out in the end, my logic was a little twisted and the
print was always executing (hence my confusion), the Hash was behaving
perfectly.

As for the Set using

require 'Set'

That's the problem with not having docs for 1.8.2, the only docs I have
cover 1.6 (and not too much of that). Suppose I'll have to get Pickaxe 2 :)

Kev
 
R

Ryan Leavengood

That's the problem with not having docs for 1.8.2, the only docs I have
cover 1.6 (and not too much of that). Suppose I'll have to get Pickaxe 2=
:)

Don't forget ri:

C:\Documents and Settings\rjl>ri Set
------------------------------------------------------------- Class: Set
Set implements a collection of unordered values with no duplicates.
This is a hybrid of Array's intuitive inter-operation facilities
and Hash's fast lookup.

Several methods accept any Enumerable object (implementing +each+)
for greater flexibility: new, replace, merge, subtract, |, &, -, ^.
...
[rest elided]

"ri -c" will also list all the classes ri knows about, in case you
aren't sure what you are looking for.

Ryan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,190
Members
46,736
Latest member
zacharyharris

Latest Threads

Top