# loop3

```;; 事前処理
;; バッファの各行を文字列のリストで返す
(save-excursion
(loop initially (goto-char (point-min))
until (eobp)
collect (thing-at-point 'line)
do (forward-line 1)))
```
```;; ループの最後まで処理したあと、返り値を指定するには、finally return節を使う
;; 連続的にリストに値を追加して返す
(loop with ret
for i from 1 to 3
do (push i ret)
finally return ret)		; => (3 2 1)
;; finally節には以下のように記述できる
(loop with ret
for i from 1 to 3
do (push i ret)
finally (return ret))		; => (3 2 1)

;; loopマクロ自体に暗黙のブロックを持っている

;; loopの中で条件分岐をすることもできる
;; 偶数のみを選択する
(loop for x in '(1 3 4 5 8)
if (evenp x) collect x)		; => (4 8)
(loop for x in '(1 3 4 5 8)
unless (oddp x) collect x)		; => (4 8)

;; ifで指定した条件式の結果がローカル変数itに格納される
;; そのため、条件式が真のときは条件式のまま返すのに
;; if CONDITION collect itと表現できる

;; 使われているシンボルを得る
(loop for sym in '("find-file" "hogehoge" "view-file")
if (intern-soft sym) collect it)	; => (find-file view-file)

;; またif節やunless節にはelseを持つことも出来る
;; 偶数と奇数を分ける
(loop for x in '(3 4 8 5 9 2)
if (evenp x)
collect x into evens
else
collect x into odds
finally return (list evens odds))	; => ((4 8 2) (3 5 9))

(loop for x in '(3 4 8 5 9 2)
unless (oddp x)
collect x into evens
else
collect x into odds
finally return (list evens odds))	; => ((4 8 2) (3 5 9))

;; ループからの脱出(return節を使うことで可能)
(loop for x in '(1 3 5 6 7)
if (evenp x) return x)		; => 6
;; named節で暗黙のブロックに名前をつけることが出来る
;; ネストしたloopからreturn-fromで脱出するために使う

;; 1≦i, j≦10において積が21になる最初の組み合わせ
(loop named found
for i from 1 to 10 do
(loop for j from 1 to 10
if (= (* i j) 21)
do (return-from found (cons i j)))) ; => (3 . 7)
``` Emacs Lispテクニックバイブル