Re: Collecting like-labelled sublists of a list
- From: Kaz Kylheku <kkylheku@xxxxxxxxx>
- Date: Wed, 30 Jul 2008 22:14:01 +0000 (UTC)
On 2008-07-29, Cortez <relativeflux@xxxxxxxxxxxxx> wrote:
I need to traverse a list of lists, where each sublist is labelled by
a number, and collect together the contents of all sublists sharing
the same label. So if I have the list -
((0 a b) (1 c d) (2 e f) (3 g h) (1 i j) (2 k l) (4 m n) (2 o p) (4 q
r) (5 s t))
Note that this is basically like join of a database onto itself,
where the number is the join key.
where the first element of each sublist is the label, I need to
produce -
((a b) (c d i j) (e f k l o p) (g h) (m n q r) (s t))
I do this with the following -
(defun test (list)
(loop for j in list
for index = (first j)
for k = (rest j)
with indices = nil
if (not (member index indices))
do (pushnew index indices)
and collect k into res
else
do (nconc (nth index res) k)
finally (return res)))
I suspect that there is a more efficient and elegant way of doing
this, however. Any suggestions welcome.
If you want efficiency for situations when such lists are large,
you probably want to use hashing to implement the join.
If the labels are within a small numeric range, like 0 to 99, you could use an
array instead of hashing:
(defun join (list)
(let ((array (make-array '(100))))
(dolist (sublist list (coerce (remove nil array) 'list))
(destructuring-bind (numeric-label &rest items) sublist
(setf (aref array numeric-label)
(append (aref array numeric-label) items))))))
Change APPEND to NCONC for the destructive version.
Brief background: this is part of a program I've written for reading
data from SDIF files, a binary format which stores sound description
data. The labelled lists represent partials in spectral analysis data
(partial-index, time, frequency).
So the labels are bounded, since they represent partials, and there are only so
many partials in the spectral analysis.
.
- References:
- Collecting like-labelled sublists of a list
- From: Cortez
- Collecting like-labelled sublists of a list
- Prev by Date: Re: Generating normally distributed randoms in CL
- Next by Date: Re: Generating normally distributed randoms in CL
- Previous by thread: Re: Collecting like-labelled sublists of a list
- Next by thread: paging all socket geniuses
- Index(es):
Relevant Pages
|