iterator 20170207.38(in MELPA)
A library to create and use elisp iterators objects.

概要

iterator.el はRubyの Enumerator のような
外部イテレータ を実現します。

# Rubyにて
# 外部イテレータとして使う
i = [1,2,3].to_enum             # => #<Enumerator: [1, 2, 3]:each>
i.next                          # => 1
i.next                          # => 2
i.next                          # => 3
i.next rescue $!
# => #<StopIteration: iteration reached an end>
# 循環リスト
i = [1,2].cycle                 # => #<Enumerator: [1, 2]:cycle>
i.next                          # => 1
i.next                          # => 2
i.next                          # => 1
i.next                          # => 2

イテレータオブジェクト(クロージャ)を作成する関数は多いですが、
<2015-05-13 Wed>時点では iterator:next
次の要素を得るくらいしかできません。

;;; リストからなるイテレータ
(let ((iter (iterator:list '(1 2 3))))
  (iterator:next iter)                  ; => 1
  (iterator:next iter)                  ; => 2
  (iterator:next iter)                  ; => 3
  (iterator:next iter)                  ; => nil
  )
;;; 指定された要素の次の要素から繰り返す
(let ((iter (iterator:sub-next '(1 2 3 4) 2)))
  (iterator:next iter)                  ; => 3
  (iterator:next iter)                  ; => 4
  (iterator:next iter)                  ; => nil
  )
;;; 指定された要素の前の要素から逆順で繰り返す
(let ((iter (iterator:sub-prec '(1 2 3 4) 2)))
  (iterator:next iter)                  ; => 1
  (iterator:next iter)                  ; => nil
  )
;;; 循環リストのイテレータ
(let ((iter (iterator:circular '(1 2 3))))
  (iterator:next iter)                  ; => 1
  (iterator:next iter)                  ; => 2
  (iterator:next iter)                  ; => 3
  (iterator:next iter)                  ; => 1
  (iterator:next iter)                  ; => 2
  )
;;; 指定された要素の次の要素から繰り返す(循環リスト)
(let ((iter (iterator:sub-next-circular '(1 2 3) 2)))
  (iterator:next iter)                  ; => 3
  (iterator:next iter)                  ; => 1
  (iterator:next iter)                  ; => 2
  (iterator:next iter)                  ; => 3
  (iterator:next iter)                  ; => 1
  )
;;; 指定された要素の前の要素から逆順で繰り返す(循環リスト)
(let ((iter (iterator:sub-prec-circular '(1 2 3) 2)))
  (iterator:next iter)                  ; => 1
  (iterator:next iter)                  ; => 3
  (iterator:next iter)                  ; => 2
  (iterator:next iter)                  ; => 1
  (iterator:next iter)                  ; => 3
  )
;;; リストに関数を適用したイテレータ
(let ((iter (iterator:apply-fun-on-list 'sqrt '(1 2 3))))
  (iterator:next iter)                  ; => 1.0
  (iterator:next iter)                  ; => 1.4142135623730951
  (iterator:next iter)                  ; => 1.7320508075688772
  (iterator:next iter)                  ; => nil
  )
;;; 指定された数の要素だけ取り出すイテレータ
(let ((iter (iterator:scroll-list '(1 2 3 4 5) 3)))
  (iterator:next iter)                  ; => (1 2 3)
  (iterator:next iter)                  ; => (2 3 4)
  (iterator:next iter)                  ; => (3 4 5)
  (iterator:next iter)                  ; => (4 5)
  (iterator:next iter)                  ; => (5)
  (iterator:next iter)                  ; => nil
  )

ちなみに、 helm でも helm-iter-list / helm-iter-next という名前で
外部イテレータがこっそり使われています。

それらをライブラリに追い出したとも言えます。

インストール

パッケージシステムを初めて使う人は
以下の設定を ~/.emacs.d/init.el の
先頭に加えてください。

(package-initialize)
(setq package-archives
      '(("gnu" . "http://elpa.gnu.org/packages/")
        ("melpa" . "http://melpa.org/packages/")
        ("org" . "http://orgmode.org/elpa/")))

初めてiteratorを使う方は
以下のコマンドを実行します。

M-x package-install iterator

アップグレードする方は、
以下のコマンドでアップグレードしてください。
そのためにはpackage-utilsパッケージが必要です。

M-x package-install package-utils (初めてアップグレードする場合のみ)
M-x package-utils-upgrade-by-name iterator


本日もお読みいただき、ありがとうございました。参考になれば嬉しいです。