patternMinor
Combinations of list elements
Viewed 0 times
listelementscombinations
Problem
It was written in Emacs Lisp and requires Common Lisp loop facility.
Can this code be improved? Did I hit any anti-patterns along the way?
Can this code be improved? Did I hit any anti-patterns along the way?
(defun combos (list)
(let* ((a (car list))
(d (cdr list))
(s (and d (combos d)))
(v (loop for c in s collect (cons a c))))
(cons (list a) (append s v))))Solution
I would suggest handling a nil input explicitly. Then you can:
Here's the code I tested with (in Scheme, since I have neither Emacs nor a CL implementation installed):
And if you really can't bear to see the empty list as one of the combinations (though it really is), just take the
Update: I installed Emacs now, so I was able to port my Scheme version to elisp and test it:
- strip out the
and(ins's binding), and just recurse directly
- strip out the
consat the bottom, leaving only theappend
Here's the code I tested with (in Scheme, since I have neither Emacs nor a CL implementation installed):
;; Requires SRFI 26
(define (combos lst)
(if (null? lst) '(())
(let* ((a (car lst))
(d (cdr lst))
(s (combos d))
(v (map (cut cons a <>) s)))
(append s v))))And if you really can't bear to see the empty list as one of the combinations (though it really is), just take the
cdr of the resulting list. It's always the first element.Update: I installed Emacs now, so I was able to port my Scheme version to elisp and test it:
(defun combos (list)
(if (null list) '(nil)
(let* ((a (car list))
(d (cdr list))
(s (combos d))
(v (mapcar (lambda (x) (cons a x)) s)))
(append s v))))Code Snippets
;; Requires SRFI 26
(define (combos lst)
(if (null? lst) '(())
(let* ((a (car lst))
(d (cdr lst))
(s (combos d))
(v (map (cut cons a <>) s)))
(append s v))))(defun combos (list)
(if (null list) '(nil)
(let* ((a (car list))
(d (cdr list))
(s (combos d))
(v (mapcar (lambda (x) (cons a x)) s)))
(append s v))))Context
StackExchange Code Review Q#18398, answer score: 5
Revisions (0)
No revisions yet.