Skip to content

Instantly share code, notes, and snippets.

@gwerbin
Last active December 8, 2022 03:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gwerbin/edbf0c865fd9f02f2372fe2a100824ba to your computer and use it in GitHub Desktop.
Save gwerbin/edbf0c865fd9f02f2372fe2a100824ba to your computer and use it in GitHub Desktop.
Collect a list into a list of pairs (an "alist")
; https://stackoverflow.com/a/40028542/2954547
(defun collect-alist-loop (items)
(unless (evenp (length items))
(error "Items must have an even number of pairs!"))
(loop
:for (a b)
:on items
:by #'cddr
:collect (cons a b)))
(defun collect-alist-mut (items)
(unless (evenp (length items))
(error "Items must have an even number of pairs!"))
(do ((accum '()))
((null items)
(nreverse accum))
(let ((key (pop items))
(val (pop items)))
(push (cons key val) accum))))
(defun collect-alist-rec (items)
(unless (evenp (length items))
(error "Items must have an even number of pairs!"))
(labels ((recur (&optional (items items) (accum '()))
(if (null items)
(nreverse accum)
(let* ((key (car items))
(val (cadr items))
(pair (cons key val)))
(recur (cddr items) (cons pair accum))))))
(recur)))
(format t "~A~%" (collect-alist-loop '(a b c d e f)))
(format t "~A~%" (collect-alist-mut '(a b c d e f)))
(format t "~A~%" (collect-alist-rec '(a b c d e f)))
(define (collect-alist-rec items)
(unless (even? (length items))
(error "Items must have an even number of pairs!"))
(let loop ((items items)
(accum '()))
(if (null? items)
(reverse accum)
(let* ((key (car items))
(val (cadr items))
(pair (cons key val)))
(loop (cddr items) (cons pair accum))))))
(print (collect-alist-rec '(a b c d e f)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment