help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: best way to get the list of unique keys from 2 alists


From: Drew Adams
Subject: RE: best way to get the list of unique keys from 2 alists
Date: Fri, 16 Dec 2005 16:13:29 -0800

    I've got 2 alists of (SYMBOL . "STRING") pairs, and I need to get the
    list of unique symbol names to pass to completing-read as its TABLE
    argument: (("SYMBOL-NAME") ...)

    I know about remove-duplicates and union, but I'd like to avoid using
    cl*.el functions.

    Since completing-read seems to ignore nil entries in TABLE, this is what
    I've got now:

    (nconc (mapcar (lambda (assoc)
                      (list (symbol-name (car assoc))))
                    alist-1)
            (mapcar (lambda (assoc)
                      (or (assq (car assoc) alist-1)
                          (list (symbol-name (car assoc)))))
                    alist-2))

    Is there a cleaner way?

That looks good to me.

You could always define union or remove-duplicates, but removing duplicates
would be less efficient than what you're doing (consing up the second list
completely, just to perhaps remove stuff). Anyway, here are non-destructive
versions of remove-duplicates and union, FWIW:

(defun remove-duplicates (list)
  "Copy of LIST with duplicate elements removed.
Tested with `equal'."
  (let ((tail list)
        new)
    (while tail
      (unless (member (car tail) new)
         (push (car tail) new))
      (pop tail))
    (nreverse new)))

(defun union (list1 list2)
  "Combine LIST1 and LIST2 using a set-union operation.
The result list contains all items that appear in either LIST1 or
LIST2.  This is a non-destructive function; it copies the data if
necessary."
  (cond ((null list1) list2)
        ((null list2) list1)
        ((equal list1 list2) list1)
        (t
         (or (>= (length list1) (length list2))
             (setq list1 (prog1 list2 (setq list2 list1)))) ; Swap them.
         (while list2
           (unless (member (car list2) list1)
               (setq list1 (cons (car list2) list1)))
           (setq list2 (cdr list2)))
         list1)))





reply via email to

[Prev in Thread] Current Thread [Next in Thread]