Posted 2014-06-09 15:00:00 GMT
(LISP Library 365参加エントリ)
LISP Library 365 の161日目です。
cl-enumerationは、Marco Antoniotti氏作のCommon LispでJava等のイテレーターや列挙型を模したライブラリです。
パッケージ名 | cl-enumeration |
Quicklisp | ○ |
CLiKi | CLiki: CL Enumerations |
Quickdocs | http://quickdocs.org/cl-enumeration |
common-lisp.net | COMMON LISP ENUMERATIONS |
(ql:quickload :enumerations)
どんな関数があるかは、Quickdocsで確認できます。
リスト、ベクタ、文字列、ハッシュテーブル等をenumerateで変換することにより、has-next-pや、nextを利用できるようになり、外部イテレータとして利用できるようになります。
(enum:enumerate #(1 2 3 4))
;=> #<(SIMPLE-VECTOR 4) enumeration {1018199003}>
(loop :with e := (enum:enumerate '(1 2 3 4))
:while (enum:has-next-p e) :do (print (enum:next e)))
;>>
;>> 1
;>> 2
;>> 3
;>> 4
;=> NIL
また、便利構文としてforeachが用意されていて、enumeration型はもとより標準でenumeration型に変換できるものは、そのまま記述可能です。
(enum:foreach (e (enum:enumerate #(1 2 3 4)))
:collect e)
;=> (1 2 3 4)
(enum:foreach (e #(1 2 3 4))
:collect e)
;=> (1 2 3 4)
LOOPに似たキーワードが利用できますが、foreachはLOOPに展開されるマクロになっているためだったりします。
(enum:foreach (e #(1 2 3 4))
:collect e)
===>
(LET* ((#:ENUMERATION-VAR-2399
(|enum|:ENUMERATE (|enum|:ENUMERATE #(1 2 3 4))))
(E (|enum|:CURRENT #:ENUMERATION-VAR-2399)))
(LOOP |enum|::WHILE (|enum|:HAS-NEXT-P #:ENUMERATION-VAR-2399)
DO (SETF E (|enum|:NEXT #:ENUMERATION-VAR-2399))
:COLLECT E))
(enum:foreach (e "maporfic")
:collect e)
;=> (#\m #\a #\p #\o #\r #\f #\i #\c)
(enum:foreach (i #(1 2 3 4))
:collect i)
;=> (1 2 3 4)
(defvar *table*
(*:alist-hash-table '((:A . 65) (:B . 66) (:C . 67) (:D . 68) (:E . 69) (:F . 70) (:G . 71)
(:H . 72) (:I . 73) (:J . 74) (:K . 75) (:L . 76) (:M . 77) (:N . 78)
(:O . 79) (:P . 80) (:Q . 81) (:R . 82) (:S . 83) (:T . 84) (:U . 85)
(:V . 86) (:W . 87) (:X . 88) (:Y . 89) (:Z . 90))))
(enum:foreach (v *table*)
:collect v)
;=> (65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90)
ハッシュテーブルは値だけ取得可能。
今回は、cl-enumerationを紹介してみました。
なんとなくLOOPの不便なところを埋めるような感じで使ってしまいそうなライブラリです。