Yet Another Common Lisp Problems #5 take
ホームページ移転のお知らせ - Yahoo!ジオシティーズ●問題5
リスト xs の先頭から n 個の要素を取り出す関数 take xs n を定義してください。
> (take '(a b c d e) 3) (a b c) > (take '(a b c d e) 0) () > (take '(a b c d e) 6) (a b c d e)
無駄に色んな書き方をしてみた。
;; 再帰で (defun take-rec (xs n) (if (or (zerop n) (null xs)) nil (cons (car xs) (take%0 (cdr xs) (1- n))))) ;; subseq は cheat な気分 (defun take-subseq#1 (xs n) (subseq xs 0 (min n (length xs)))) (defun take-subseq#2 (xs n) (if (>= n (length xs)) xs (subseq xs 0 n))) ;; loop で #1 (require "cmu_loop") (defun take-loop#1 (xs n) (loop for n from n above 0 for x = xs then (cdr x) while x collect (car x))) ;; loop で #2 (defun take-loop#2 (xs n) (loop repeat n for x on xs ; for VAR on LIST で cdr を歩けるらしい while x collect (car x))) ;; do で (defun take-do (xs n) (do ((xs xs (cdr xs)) (n n (1- n)) (acc nil (cons (car xs) acc))) ((or (zerop n) (null xs)) (nreverse acc)))) ;; mapcar + values + make-list (defun take-mapcar (xs n) (mapcar #'values xs (make-list n)))
再帰か subseq が好きかな。mapcar は見た目はスッキリしてるけど、読んだとき (?_?) ってなりそう。