Hatena::Groupcadr

わだばLisperになる このページをアンテナに追加 RSSフィード

2004 | 12 |
2005 | 01 | 02 | 07 | 10 | 11 |
2006 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 11 |

2008-06-26

サンプルコードによるLOOPマクロ入門 (2)

| 23:11 | サンプルコードによるLOOPマクロ入門 (2) - わだばLisperになる を含むブックマーク はてなブックマーク - サンプルコードによるLOOPマクロ入門 (2) - わだばLisperになる

分割(Destructuring)

書くネタがある訳じゃないのですが、とりあえず続きもので行きます。

LOOPマクロの便利な機能として、LOOP変数で分割代入が使えるというのがあります。

for 変数 in

のところに、

for (変数 変数) in

という風に分割したい形式に合せて指定すると、それぞれの変数に分割された内容が代入されます。

(defvar *data* '((0 A) (1 B) (2 C) (3 D) (4 E) (5 F) (6 G) (7 H) (8 I)))
  • 各々の子リストの内容を逆転
(loop :for (x y) :in *data* :collect (list y x))
;=> ((A 0) (B 1) (C 2) (D 3) (E 4) (F 5) (G 6) (H 7) (I 8))
  • ドット対で指定
(loop :for (x . y) :in *data* :collect (list x y))
;=> ((0 (A)) (1 (B)) (2 (C)) (3 (D)) (4 (E)) (5 (F)) (6 (G)) (7 (H)) (8 (I)))
  • 複雑なもの
(defvar *data2* 
  '(((0 (A))) ((1 (B))) ((2 (C))) ((3 (D))) ((4 (E))) ((5 (F))) ((6 (G)))
    ((7 (H))) ((8 (I)))))

(loop :for ((x (y))) :in *data2* :collect x :collect y)
;=> (0 A 1 B 2 C 3 D 4 E 5 F 6 G 7 H 8 I)

:COLLECTは複数回使えます。

  • 他の構文との比較
;; dolistで
(let (res)
  (dolist (x *data2* (nreverse res))
    (destructuring-bind ((x (y))) x
      (push x res)
      (push y res))))

;;mapcanで
(mapcan (lambda (x)
          (destructuring-bind ((x (y))) x
            (list x y)))
        *data2*)