2009/11/13

Lisp シーケンス操作関数の続き

シーケンス反復関数
count, find, position, remove, substituteがある
指定できるキーワードとしてeqlで比較されるが、testキーワードに2引数関数を渡すことで比較関数を変更できる
from-endキーワードで逆順に処理、keyに1引数関数を渡すこともできる。
start, endキーワードで開始位置や終了位置の変更が可能

それぞれの関数にsuffixとして"-if, -if-not"をつけたものがある。
remove-if-notはPerlのgrepと同様の処理になる
下記は#\fから始まる文字列を取得

* (remove-if-not #'(lambda (x) (char= (elt x 0) #\f)) #("foo" "bar"))

#("foo")


重複を取り除くremove-duplicatesもある

シーケンス全体を一度に扱う関数
concatenate, copy-seq reverse
concatenateは1引数目に作成するタイプを入れる

* (concatenate 'string "abc" '#(#\d #\e #\f))
"abcdef"

* (reverse #(1 2 3 4))
#(4 3 2 1)

* (defvar *x* nil)
*X*

* (setf *x* (copy-seq #(1 2 3)))
#(1 2 3)

* *x*
#(1 2 3)


ソートとマージ
sort, stable-sort, mergeがある
sortとstable-sortの違いは述語によって等価と判断された要素の順番がかわるかどうからしい。
sort, stable-sortは破壊的関数なので必ず返り値を使用すること
(sort シーケンス 述語)
(merge シーケンス1 シーケンス2 述語)

部分シーケンス操作
(subseq シーケンス 開始インデックス 終了インデックス)
Perlのsubstrと一緒

部分シーケンスを見つける関数
search

(position #\b "foobarbaz") → 3
(search "bar" "foobarbaz") → 3

二つのシーケンスから異なる部分を見つけるのに[I]mismatch[/I]が利用できる。
キーワードとしてstart1, end1, start2, end2を利用可能
[CODE]
* (mismatch "foobarbaz" "bar")
0
* (mismatch "foobarbaz" "foom")
3
* (mismatch "foobarbaz" "bar" :start1 6)
8


シーケンス述語
every, some, notany, notevery

* (setf *x* #(1 2 3 4 5))
#(1 2 3 4 5)
* (every #'evenp *x*)
NIL
* (some #'evenp *x*)
T
* (notany #'evenp *x*)
NIL
* (notevery #'evenp *x*)


マッピング関数
map, map-into, reduce
map-intoは第1引数のシーケンスに第2引数のシーケンスをセットする

Perlに比べるとすげー多い。
List:MoreUtilsを標準で組み込んだ感じ

ハッシュテーブル
make-hash-table, gethash,remhash, clrhash
gethashの返り値は多値なのでmultiple-bind-valueで多値を受け取れる

(defparameter *h* (make-hash-table))
(gethash 'foo *h*) → NIL
(setf (gethash 'foo *h*) 'quux)
(gethash 'foo *h*) → NIL
(multiple-bind-value (value present) (gethash 'foo *h*))

setfとgethashでキーにnilを設定すると値がnilになる
remhashでキーを削除できる。
clrhashですべてのキーと値を削除できる

0 件のコメント:

コメントを投稿