all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* Hash tables - how to look up values?
@ 2012-07-04 13:48 Thorsten Jolitz
  2012-07-04 14:09 ` Teemu Likonen
  2012-07-04 14:09 ` Bastien
  0 siblings, 2 replies; 6+ messages in thread
From: Thorsten Jolitz @ 2012-07-04 13:48 UTC (permalink / raw
  To: help-gnu-emacs


Hi List, 
I would need a function that does the opposite of 

,--------------------
| (gethash key table)
`--------------------

i.e. something like 

,-------------------
| (getkey val table)
`-------------------

that returns the corresponding key of a known (string) value in a hash
table (similar to 'rassoc' for alists). 

I could not find such a function - does it exist already?

-- 
cheers,
Thorsten





^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Hash tables - how to look up values?
       [not found] <mailman.4023.1341409554.855.help-gnu-emacs@gnu.org>
@ 2012-07-04 13:59 ` Pascal J. Bourguignon
  2012-07-04 14:21   ` Thorsten Jolitz
  0 siblings, 1 reply; 6+ messages in thread
From: Pascal J. Bourguignon @ 2012-07-04 13:59 UTC (permalink / raw
  To: help-gnu-emacs

Thorsten Jolitz <tjolitz@googlemail.com> writes:

> Hi List, 
> I would need a function that does the opposite of 
>
> ,--------------------
> | (gethash key table)
> `--------------------
>
> i.e. something like 
>
> ,-------------------
> | (getkey val table)
> `-------------------
>
> that returns the corresponding key of a known (string) value in a hash
> table (similar to 'rassoc' for alists). 
>
> I could not find such a function - does it exist already?

rassoc returns the first hit, because lists, even association lists are
ordered.  Hash tables are not ordered.  We can write something similar,
returning the first hit, but there's no guarantee the first will always
be the same.


(require 'cl)

(defun* getkey (val table &key (test (function eql)) (default nil))
   ;; (hash-table-test table)  is for keys, not for values…
   (maphash (lambda (k v) 
              (when (funcall test val v) (return-from getkey k)))
            table)
   default)

(let ((h (make-hash-table)))
  (setf (gethash :one h) "un"
        (gethash :two h) "deux"
        (gethash :a   h) "un")
  (getkey "un" h :test (function string=)))
--> :one ; or :a, who knows?

I'd rather write:

(defun* getkeys (val table &key (test (function eql)))
   ;; (hash-table-test table)  is for keys, not for values…
   (let ((keys '()))
     (maphash (lambda (k v) 
                 (when (funcall test val v) (push k keys)))
              table)
     keys))

(let ((h (make-hash-table)))
  (setf (gethash :one h) "un"
        (gethash :two h) "deux"
        (gethash :a   h) "un")
  (getkeys "un" h :test (function string=)))
--> (:a :one)


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
A bad day in () is better than a good day in {}.


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Hash tables - how to look up values?
  2012-07-04 13:48 Hash tables - how to look up values? Thorsten Jolitz
@ 2012-07-04 14:09 ` Teemu Likonen
  2012-07-04 14:09 ` Bastien
  1 sibling, 0 replies; 6+ messages in thread
From: Teemu Likonen @ 2012-07-04 14:09 UTC (permalink / raw
  To: Thorsten Jolitz; +Cc: help-gnu-emacs

Thorsten Jolitz [2012-07-04 15:48:09 +0200] wrote:

> that returns the corresponding key of a known (string) value in a hash
> table (similar to 'rassoc' for alists).
>
> I could not find such a function - does it exist already?

There is no such thing. You need to traverse the hash table with maphash
and look for your value. This is obviously slower than gethash but this
is how hash tables work.

If you need fast two-way access in your programs you could create your
own access functions which synchronize two hash tables and thus get fast
two-way access.



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Hash tables - how to look up values?
  2012-07-04 13:48 Hash tables - how to look up values? Thorsten Jolitz
  2012-07-04 14:09 ` Teemu Likonen
@ 2012-07-04 14:09 ` Bastien
  2012-07-04 14:31   ` Thorsten Jolitz
  1 sibling, 1 reply; 6+ messages in thread
From: Bastien @ 2012-07-04 14:09 UTC (permalink / raw
  To: Thorsten Jolitz; +Cc: help-gnu-emacs

Hi Thorsten,

Thorsten Jolitz <tjolitz@googlemail.com> writes:

> I would need a function that does the opposite of 
>
> ,--------------------
> | (gethash key table)
> `--------------------
>
> i.e. something like 
>
> ,-------------------
> | (getkey val table)
> `-------------------
>
> that returns the corresponding key of a known (string) value in a hash
> table (similar to 'rassoc' for alists). 
>
> I could not find such a function - does it exist already?

I don't think so.  But here is a start:

(let (key-found)
  (maphash (lambda (key val)
	     (when (equal val "my_value")
	       (setq key-found key)))
	   hashtest)
  key-found)

Of course, the shortcoming is that it stops at the first key it finds,
and discards multiple keys if several have the same value.

HTH,

-- 
 Bastien



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Hash tables - how to look up values?
  2012-07-04 13:59 ` Pascal J. Bourguignon
@ 2012-07-04 14:21   ` Thorsten Jolitz
  0 siblings, 0 replies; 6+ messages in thread
From: Thorsten Jolitz @ 2012-07-04 14:21 UTC (permalink / raw
  To: help-gnu-emacs

"Pascal J. Bourguignon" <pjb@informatimago.com> writes:

>> I could not find such a function - does it exist already?
>
> rassoc returns the first hit, because lists, even association lists are
> ordered.  Hash tables are not ordered.  We can write something similar,
> returning the first hit, but there's no guarantee the first will always
> be the same.
>
>
> (require 'cl)
>
> (defun* getkey (val table &key (test (function eql)) (default nil))
>    ;; (hash-table-test table)  is for keys, not for values…
>    (maphash (lambda (k v) 
>               (when (funcall test val v) (return-from getkey k)))
>             table)
>    default)
>
> (let ((h (make-hash-table)))
>   (setf (gethash :one h) "un"
>         (gethash :two h) "deux"
>         (gethash :a   h) "un")
>   (getkey "un" h :test (function string=)))
> --> :one ; or :a, who knows?
>
> I'd rather write:
>
> (defun* getkeys (val table &key (test (function eql)))
>    ;; (hash-table-test table)  is for keys, not for values…
>    (let ((keys '()))
>      (maphash (lambda (k v) 
>                  (when (funcall test val v) (push k keys)))
>               table)
>      keys))
>
> (let ((h (make-hash-table)))
>   (setf (gethash :one h) "un"
>         (gethash :two h) "deux"
>         (gethash :a   h) "un")
>   (getkeys "un" h :test (function string=)))
> --> (:a :one)

Great! Thats most amazing about Emacs and its community - if you ask for
a functionality that does not yet exists, it might well exist 5 minutes
later just because you asked for it. 

Thanks a lot, exactly what I need. 

-- 
cheers,
Thorsten




^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Hash tables - how to look up values?
  2012-07-04 14:09 ` Bastien
@ 2012-07-04 14:31   ` Thorsten Jolitz
  0 siblings, 0 replies; 6+ messages in thread
From: Thorsten Jolitz @ 2012-07-04 14:31 UTC (permalink / raw
  To: help-gnu-emacs

Bastien <bzg@gnu.org> writes:

Hi Bastien,

>> I could not find such a function - does it exist already?
>
> I don't think so.  But here is a start:
>
> (let (key-found)
>   (maphash (lambda (key val)
> 	     (when (equal val "my_value")
> 	       (setq key-found key)))
> 	   hashtest)
>   key-found)
>
> Of course, the shortcoming is that it stops at the first key it finds,
> and discards multiple keys if several have the same value.

Thanks, now I even have the 'agony of choice' (is that how they call it
in English?), but I might very well need both solutions - return the
first or all values found.

-- 
cheers,
Thorsten




^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2012-07-04 14:31 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-07-04 13:48 Hash tables - how to look up values? Thorsten Jolitz
2012-07-04 14:09 ` Teemu Likonen
2012-07-04 14:09 ` Bastien
2012-07-04 14:31   ` Thorsten Jolitz
     [not found] <mailman.4023.1341409554.855.help-gnu-emacs@gnu.org>
2012-07-04 13:59 ` Pascal J. Bourguignon
2012-07-04 14:21   ` Thorsten Jolitz

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.