From: Jim Newton
Subject: getting some key in a hash table
Date: 
Message-ID: <2lti15Ffr90lU1@uni-berlin.de>
Is there any way to get some key of a hash table?
I do not care which one I get, any one will do.

The function maphash will map a function over ALL
the key/value pairs of the hash table, but i only
one to get one element.  I could build some sort
of catch/throw around a maphash but that seems a
bit excessive.

-jim

From: JP Massar
Subject: Re: getting some key in a hash table
Date: 
Message-ID: <hn4jf0d224edqji2egcjh18nhr3r5ebd1b@4ax.com>
On Sat, 17 Jul 2004 21:58:36 +0200, Jim Newton <·····@rdrop.com>
wrote:

>Is there any way to get some key of a hash table?
>I do not care which one I get, any one will do.
>
>The function maphash will map a function over ALL
>the key/value pairs of the hash table, but i only
>one to get one element.  I could build some sort
>of catch/throw around a maphash but that seems a
>bit excessive.
>
 
Do a RETURN-FROM instead of using catch/throw.

(block exit
  (maphash 
   (lambda (key val) (declare (ignore val)) 
      (return-from exit key))) 
  *my-hash*)

You need to deal with an empty hash table elsewise.
From: Steven M. Haflich
Subject: Re: getting some key in a hash table
Date: 
Message-ID: <nhjKc.93452$aT7.51467@newssvr29.news.prodigy.com>
JP Massar wrote:

> Do a RETURN-FROM instead of using catch/throw.
> 
> (block exit
>   (maphash 
>    (lambda (key val) (declare (ignore val)) 
>       (return-from exit key))) 
>   *my-hash*)

Many implementations will turn a return-from that crosses
a lambda boundary into the equivalent of a catch-throw.

Perhaps if Jim could explain his notion of "excessive"
responses could be more focussed.  I suspect efficiency
may have been the thing in his mind, but I can't be sure
whether it is efficiency at execution time or efficiency
in the size of the source code it takes for the programmer
to express what he wants.  The alternative that uses
with-hash-table-iterator suggested in a subsequent messaage
is very elegant with regard to terse expression, but I
suspect it is more expensive at runtime since it will
probably construct a closure that will be called only once.
The maphash solution needs only a null closure...
From: Frode Vatvedt Fjeld
Subject: Re: getting some key in a hash table
Date: 
Message-ID: <2h7jt2f563.fsf@vserver.cs.uit.no>
JP Massar wrote:

>> Do a RETURN-FROM instead of using catch/throw.
>> (block exit
>>   (maphash    (lambda (key val) (declare (ignore val))
>> (return-from exit key)))   *my-hash*)

"Steven M. Haflich" <·················@alum.mit.edu> writes:

> Many implementations will turn a return-from that crosses a lambda
> boundary into the equivalent of a catch-throw.

But then again, an implementation might inline maphash, which in turn
can cause the lambda to be inlined, in which case the return-from
becomes "efficient".

> Perhaps if Jim could explain his notion of "excessive" responses
> could be more focussed.  I suspect efficiency may have been the
> thing in his mind, but I can't be sure whether it is efficiency at
> execution time or efficiency in the size of the source code it takes
> for the programmer to express what he wants.  The alternative that
> uses with-hash-table-iterator suggested in a subsequent messaage is
> very elegant with regard to terse expression, but I suspect it is
> more expensive at runtime since it will probably construct a closure
> that will be called only once.  The maphash solution needs only a
> null closure...

I believe the maphash closure will likely have to close over some sort
of identifier for the exit block (if maphash isn't inlined, that
is..), so it won't be a null closure.

All in all, I think it's futile to consider efficiency at this level,
at least for a Lisp beginner (or should I say
"non-implementor-of-the-implementation-in-question"), except of course
by way of profiling or disassembly.

-- 
Frode Vatvedt Fjeld
From: Jeremy Yallop
Subject: Re: getting some key in a hash table
Date: 
Message-ID: <slrncfj54j.gfq.jeremy@maka.cl.cam.ac.uk>
Jim Newton wrote:
> Is there any way to get some key of a hash table?
> I do not care which one I get, any one will do.
> 
> The function maphash will map a function over ALL
> the key/value pairs of the hash table, but i only
> one to get one element.  I could build some sort
> of catch/throw around a maphash but that seems a
> bit excessive.

(nth-value 1 (with-hash-table-iterator (fn hash-table) (fn)))

<http://www.franz.com/support/documentation/6.2/ansicl/dictentr/with-has.htm>

Jeremy.
From: Albert Reiner
Subject: Re: getting some key in a hash table
Date: 
Message-ID: <vw8wu12jp5i.fsf@berry.phys.ntnu.no>
>                          I could build some sort
> of catch/throw around a maphash but that seems a
> bit excessive.

I am curious: Why is avoiding catch/throw a good idea?  Performance?

Albert.
From: Peter Seibel
Subject: Re: getting some key in a hash table
Date: 
Message-ID: <m3k6x1jqtk.fsf@javamonkey.com>
Jim Newton <·····@rdrop.com> writes:

> Is there any way to get some key of a hash table?
> I do not care which one I get, any one will do.
>
> The function maphash will map a function over ALL the key/value
> pairs of the hash table, but i only one to get one element. I could
> build some sort of catch/throw around a maphash but that seems a bit
> excessive.

And from the why-not-use-loop-for-everything dept.:

  (loop for key being the hash-keys in hash return key)

Or if you want a random key:

  (loop with nth = (random (hash-table-count hash))
        for key being the hash-keys in hash
        for i from 0
        when (= i nth) return key)

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp