2012-04-02

Intro to Mathematica Pattern Matching for Lisp Programers

updated

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))

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.

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).

solution and explanation in Mathematica and Scheme lisp, Qi lisp, at http://xahlee.org/UnixResource_dir/writ/notations_mma.html