unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
* "assoc" for returning ALL associations for a given key
@ 2009-05-05  8:59 florian
  2009-05-05 10:07 ` Juanma Barranquero
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: florian @ 2009-05-05  8:59 UTC (permalink / raw)
  To: help-gnu-emacs


I somehow suspect this question must have been discussed dozens of
times before, but well ...

As is well known, association lists differ from hashes in that the
same key can occur several times, and (assoc KEY ALIST) will return
only the first such occurrence.

Consequently, a convenient method for changing the value of an
association is to simply conse the new association to the front of the
alist, which will make any old associations with the same key
"invisible" (even if that feels kind of messy to me).

I am not wondering, however, whether it is generally better to use
hashes; rather, I am musing about whether the fact that association
lists may contain the same key several times could be seen as an
advantage: An alist could be the obvious place to store information
such as, e.g.,  "In which directories do I have a file with basename
X?", where X would be the key, and the directories, the values.

I have found no function comparable to assoc to cater for such a need,
and have thus written one for myself:

    (defun assocs (key alist)
      "Like `assoc', but return all elements of ALIST whose car is
`equal' to KEY.
In other words, return a subset of ALIST."
      (delq nil
	    (mapcar '(lambda (cons-cell)
		       (if (equal (car cons-cell) key)
			   cons-cell))
		    alist)))

But I am wondering whether that would have been necessary - perhaps I
am overlooking something? Otherwise, would anybody care to comment
about the efficiency of the above function?

Many thanks for your thoughts!

Florian


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

* Re: "assoc" for returning ALL associations for a given key
  2009-05-05  8:59 "assoc" for returning ALL associations for a given key florian
@ 2009-05-05 10:07 ` Juanma Barranquero
  2009-05-05 10:15 ` Pascal J. Bourguignon
  2009-05-06 10:10 ` Nikolaj Schumacher
  2 siblings, 0 replies; 4+ messages in thread
From: Juanma Barranquero @ 2009-05-05 10:07 UTC (permalink / raw)
  To: florian; +Cc: help-gnu-emacs

On Tue, May 5, 2009 at 10:59, florian <lorian@fsavigny.de> wrote:

> But I am wondering whether that would have been necessary - perhaps I
> am overlooking something?

If you use the CL package (included in Emacs), `remove*' and friends
can be used for that:

  (remove* nil ALIST :key '(lambda (item) (equal (car item) KEY)))
  (remove-if-not (lambda (item) (equal item KEY)) ALIST :key 'car)

etc.

    Juanma




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

* Re: "assoc" for returning ALL associations for a given key
  2009-05-05  8:59 "assoc" for returning ALL associations for a given key florian
  2009-05-05 10:07 ` Juanma Barranquero
@ 2009-05-05 10:15 ` Pascal J. Bourguignon
  2009-05-06 10:10 ` Nikolaj Schumacher
  2 siblings, 0 replies; 4+ messages in thread
From: Pascal J. Bourguignon @ 2009-05-05 10:15 UTC (permalink / raw)
  To: help-gnu-emacs

florian <lorian@fsavigny.de> writes:
> [...]
> But I am wondering whether that would have been necessary - perhaps I
> am overlooking something? Otherwise, would anybody care to comment
> about the efficiency of the above function?

(require 'cl)
(remove* key a-list :key (function car) :test-not (function eql))


(let ((key :one)
      (a-list '((:one . "un")   (:two . "deux")
                (:one . "eins") (:two . "zwei")
                (:one . "one")  (:two . "two"))))
  (remove* key a-list :key (function car) :test-not (function eql)))
-> ((:one . "un") (:one . "eins") (:one . "one"))



-- 
__Pascal Bourguignon__


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

* Re: "assoc" for returning ALL associations for a given key
  2009-05-05  8:59 "assoc" for returning ALL associations for a given key florian
  2009-05-05 10:07 ` Juanma Barranquero
  2009-05-05 10:15 ` Pascal J. Bourguignon
@ 2009-05-06 10:10 ` Nikolaj Schumacher
  2 siblings, 0 replies; 4+ messages in thread
From: Nikolaj Schumacher @ 2009-05-06 10:10 UTC (permalink / raw)
  To: florian; +Cc: help-gnu-emacs

florian <lorian@fsavigny.de> wrote:

>     (defun assocs (key alist)
>       "Like `assoc', but return all elements of ALIST whose car is
> `equal' to KEY.
> In other words, return a subset of ALIST."
>       (delq nil
> 	    (mapcar '(lambda (cons-cell)
> 		       (if (equal (car cons-cell) key)
> 			   cons-cell))
> 		    alist)))
>
> But I am wondering whether that would have been necessary - perhaps I
> am overlooking something? Otherwise, would anybody care to comment
> about the efficiency of the above function?

A lot of temporary cons objects are created, so it's probably not the
most efficient way of doing this.

If efficiency is really critical, you should build the list yourself.

Or maybe create no list at all, if appropriate...

(dolist (el lst)
   (when (equal (car el) key)
      (do-stuff-here ...

That's easier on the eyes, too. ;)

regards,
Nikolaj Schumacher




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

end of thread, other threads:[~2009-05-06 10:10 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-05-05  8:59 "assoc" for returning ALL associations for a given key florian
2009-05-05 10:07 ` Juanma Barranquero
2009-05-05 10:15 ` Pascal J. Bourguignon
2009-05-06 10:10 ` Nikolaj Schumacher

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).