comp.lang.idl-pvwave archive
Messages from Usenet group comp.lang.idl-pvwave, compiled by Paulo Penteado

Home » Public Forums » archive » Re: HASH -- bug, or "feature"?
Show: Today's Messages :: Show Polls :: Message Navigator
E-mail to friend 
Switch to threaded view of this topic Create a new topic Submit Reply
Re: HASH -- bug, or "feature"? [message #75871] Thu, 21 April 2011 04:20
Gray is currently offline  Gray
Messages: 253
Registered: February 2010
Senior Member
On Apr 20, 6:09 pm, Paulo Penteado <pp.pente...@gmail.com> wrote:
> On Apr 20, 6:26 pm, Gray <grayliketheco...@gmail.com> wrote:
>
>> This all makes perfect sense... except that it isn't really useful for
>> me.  I had been using a hash so that I could retrieve and store
>> information (in the form of structures) about particular stars by
>> indexing with star IDs and not having to search over arrays or lists
>> for individual members.  When I had information for a set of stars
>> where some but not all were already in the hash, I would do something
>> like this:
>
>> tmp = replicate({star},n_new)
>> old = where(star_hash.haskey(new_ids),n_old)
>> if (n_old gt 0) then tmp[old] =
>> (star_hash[new_ids[old]].values()).toarray()
>> tmp.info = new_info & tmp.id = new_ids
>> star_hash[new_ids] = tmp
>
> I have a subclass for ordered hashes, which I could clean up and make
> public if there is interest. However, I do not see why it is needed
> above. If I understand it right, you want to put the new elements in
> the hash, without overwriting any preexisting elements. Would it not
> be the same as just
>
> tmp=replicate({star},n_new)
> tmp.info=new_info
> tmp.id=new_ids
> new=where(~star_hash.haskey(new_ids),/null)
> star_hash[new_ids[new]]=tmp[new]
>
> ?
>
> The work being just to avoid overwriting the preexisting elements. If
> they could be overwritten, it would be just
>
> tmp=replicate({star},n_new)
> tmp.info=new_info
> tmp.id=new_ids
> star_hash[new_ids]=tmp

It's worse than that. tmp.info = new_info was shorthand for updating
the relevant structure tags with the new information; however, there
are other tags with old information that I don't want to overwrite.
So I need to preserve some stuff and overwrite others, which is why I
had to do the complicated jig.
Re: HASH -- bug, or "feature"? [message #75873 is a reply to message #75871] Wed, 20 April 2011 15:09 Go to previous message
penteado is currently offline  penteado
Messages: 866
Registered: February 2018
Senior Member
Administrator
On Apr 20, 6:26 pm, Gray <grayliketheco...@gmail.com> wrote:
> This all makes perfect sense... except that it isn't really useful for
> me.  I had been using a hash so that I could retrieve and store
> information (in the form of structures) about particular stars by
> indexing with star IDs and not having to search over arrays or lists
> for individual members.  When I had information for a set of stars
> where some but not all were already in the hash, I would do something
> like this:
>
> tmp = replicate({star},n_new)
> old = where(star_hash.haskey(new_ids),n_old)
> if (n_old gt 0) then tmp[old] =
> (star_hash[new_ids[old]].values()).toarray()
> tmp.info = new_info & tmp.id = new_ids
> star_hash[new_ids] = tmp

I have a subclass for ordered hashes, which I could clean up and make
public if there is interest. However, I do not see why it is needed
above. If I understand it right, you want to put the new elements in
the hash, without overwriting any preexisting elements. Would it not
be the same as just

tmp=replicate({star},n_new)
tmp.info=new_info
tmp.id=new_ids
new=where(~star_hash.haskey(new_ids),/null)
star_hash[new_ids[new]]=tmp[new]

?

The work being just to avoid overwriting the preexisting elements. If
they could be overwritten, it would be just

tmp=replicate({star},n_new)
tmp.info=new_info
tmp.id=new_ids
star_hash[new_ids]=tmp
Re: HASH -- bug, or "feature"? [message #75874 is a reply to message #75873] Wed, 20 April 2011 14:26 Go to previous message
Gray is currently offline  Gray
Messages: 253
Registered: February 2010
Senior Member
On Apr 20, 4:33 pm, Mark Piper <mpi...@ittvis.com> wrote:
> Here's an example of the technique Mike suggests:
>
> IDL> names = list('red', 'green', 'blue')
> IDL> colors = hash()
> IDL> colors[names[0]] = [255,0,0]
> IDL> colors[names[1]] = [0,255,0]
> IDL> colors[names[2]] = [0,0,255]
>
> IDL> print, colors ; order is mangled
> green:        0     255       0
> blue:        0       0     255
> red:      255       0       0
>
> IDL> foreach n, names do print, n, colors[n] ; ordered
> red     255       0       0
> green       0     255       0
> blue       0       0     255
>
> This also works with an array (and a FOR loop) instead of a list.
>
> mp

This all makes perfect sense... except that it isn't really useful for
me. I had been using a hash so that I could retrieve and store
information (in the form of structures) about particular stars by
indexing with star IDs and not having to search over arrays or lists
for individual members. When I had information for a set of stars
where some but not all were already in the hash, I would do something
like this:

tmp = replicate({star},n_new)
old = where(star_hash.haskey(new_ids),n_old)
if (n_old gt 0) then tmp[old] =
(star_hash[new_ids[old]].values()).toarray()
tmp.info = new_info & tmp.id = new_ids
star_hash[new_ids] = tmp

But that doesn't work, because there's no guarantee that the values I
retrieve from the hash are in the same order as the array elements I'm
storing them in. What I end up having to do is

tmp = replicate({star},n_new)
old = where(star_hash.haskey(new_ids),n_old)
foreach i,old do tmp[i] = star_hash[new_ids[i]]

...and the rest is the same. I'm not sure whether this is more
inefficient or not... maybe it isn't, thanks to toarray() being slow.
Re: HASH -- bug, or "feature"? [message #75875 is a reply to message #75874] Wed, 20 April 2011 13:33 Go to previous message
Mark Piper is currently offline  Mark Piper
Messages: 198
Registered: December 2009
Senior Member
Here's an example of the technique Mike suggests:

IDL> names = list('red', 'green', 'blue')
IDL> colors = hash()
IDL> colors[names[0]] = [255,0,0]
IDL> colors[names[1]] = [0,255,0]
IDL> colors[names[2]] = [0,0,255]

IDL> print, colors ; order is mangled
green: 0 255 0
blue: 0 0 255
red: 255 0 0

IDL> foreach n, names do print, n, colors[n] ; ordered
red 255 0 0
green 0 255 0
blue 0 0 255

This also works with an array (and a FOR loop) instead of a list.

mp
Re: HASH -- bug, or "feature"? [message #75876 is a reply to message #75875] Wed, 20 April 2011 12:50 Go to previous message
Paul Van Delst[1] is currently offline  Paul Van Delst[1]
Messages: 1157
Registered: April 2002
Senior Member
It's not a bug or a feature. It's a property of hashes. And it's not peculiar to IDL. E.g. from the Ruby pickaxe:

<quote>
Compared with arrays, hashes have one significant advantage: they can use any object as an index. However, they also
have a significant disadvantage: their elements are not ordered.
</quote>

Similarly with Python dictionaries.

Typically the need for hashes where insertion order is important leads to a subclass of Hash being created where the
order is internally tracked.

cheers,

paulv



Gray wrote:
> Can anyone tell me why, when you create a hash, the elements are not
> in the order of the keys you give? And, even worse, when you index a
> hash with an array of keys, the resulting hash does not come out in
> the same order as the array?
>
> IDL> h = hash(['a','b','c','d'],indgen(4))
> IDL> print, h
> c: 2
> a: 0
> b: 1
> d: 3
> IDL> print, h[['a','c','d']]
> c: 2
> a: 0
> d: 3
>
> This is making my bookkeeping using hashes basically impossible.
>
> --Gray
Re: HASH -- bug, or "feature"? [message #75877 is a reply to message #75876] Wed, 20 April 2011 12:19 Go to previous message
Michael Galloy is currently offline  Michael Galloy
Messages: 1114
Registered: April 2006
Senior Member
On 4/20/11 1:12 PM, Gray wrote:
> Can anyone tell me why, when you create a hash, the elements are not
> in the order of the keys you give? And, even worse, when you index a
> hash with an array of keys, the resulting hash does not come out in
> the same order as the array?
>
> IDL> h = hash(['a','b','c','d'],indgen(4))
> IDL> print, h
> c: 2
> a: 0
> b: 1
> d: 3
> IDL> print, h[['a','c','d']]
> c: 2
> a: 0
> d: 3
>
> This is making my bookkeeping using hashes basically impossible.
>
> --Gray

Hashes are not an ordered collection.

If I wanted to store something in a hash, but order was important, I
would use a list and a hash where the keys are added in the correct
order to the list and then looked up in the hash to get the value.

Mike
--
www.michaelgalloy.com
Research Mathematician
Tech-X Corporation
  Switch to threaded view of this topic Create a new topic Submit Reply
Previous Topic: HASH -- bug, or "feature"?
Next Topic: IDL syntax highlighting for GeSHI

-=] Back to Top [=-
[ Syndicate this forum (XML) ] [ RSS ] [ PDF ]

Current Time: Wed Oct 08 17:36:52 PDT 2025

Total time taken to generate the page: 0.00625 seconds