読者です 読者をやめる 読者になる 読者になる

by shigemk2

当面は技術的なことしか書かない

loop3

Emacs Lisp
;; 事前処理
;; バッファの各行を文字列のリストで返す
(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テクニックバイブル

Emacs Lispテクニックバイブル