Next: 配列, Up: シーケンス、配列、ベクター [Contents][Index]
このセクションでは任意の種類のシーケンスを許す関数を説明します。
この関数はobjectがリスト、ベクター、文字列、ブールベクター、文字テーブルならt
、それ以外はnil
をリターンする。以下のseqp
も参照のこと。
この関数はsequence内の要素の数をリターンする。sequenceがシーケンス以外、またはドットリストならwrong-type-argument
エラーをシグナルする。引数が循環リストならcircular-list
エラーをシグナルする。文字テーブルではEmacsの最大文字コードより1大きい値が常にリターンされる。
関連する関数safe-length
についてはDefinition of safe-lengthを参照のこと。
(length '(1 2 3)) ⇒ 3
(length ()) ⇒ 0
(length "foobar") ⇒ 6
(length [1 2 3]) ⇒ 3
(length (make-bool-vector 5 nil)) ⇒ 5
テキストの表現方法のstring-bytes
も参照されたい。
ディスプレー上での文字列の幅を計算する必要があるなら、文字数だけを数えて各文字のディスプレー幅を計算しないlength
ではなく、string-width
(表示されるテキストのサイズを参照)を使用すること。
sequenceがlengthより短ければ非nil
をリターンする。これはsequenceが長いリストの場合にsequenceの長さを計算するより効率的かもしれない。
sequenceがlengthより長ければ非nil
をリターンする。
sequenceの長さがlengthなら非nil
をリターンする。
この関数はindexによりインデックスづけされた、sequenceの要素をリターンする。indexの値として妥当なのは、0からsequenceの長さより1小さい数までの範囲の整数。sequenceがリストなら範囲外の値はnth
と同じように振る舞う。Definition of nthを参照のこと。それ以外なら範囲外の値はargs-out-of-range
エラーを引き起こす。
(elt [1 2 3 4] 2) ⇒ 3
(elt '(1 2 3 4) 2) ⇒ 3
;; elt
がどの文字をreturnするか明確にするためにstring
を使用
(string (elt "1234" 2))
⇒ "3"
(elt [1 2 3 4] 4) error→ Args out of range: [1 2 3 4], 4
(elt [1 2 3 4] -1) error→ Args out of range: [1 2 3 4], -1
この関数はaref
(配列を操作する関数を参照)とnth
(Definition of nthを参照)を一般化したものである。
この関数はseqr (シーケンスかレコードであること)のコピーをリターンする。コピーはオリジナルと同じオブジェクト型であり、同じ要素を同じ順序でもつ。しかしseqrが空なら長さが0の文字列やベクターと同じように関数がリターンする値はコピーではないかもしれないが、seqrと同じ型の空のオブジェクトである。
コピーに新しい要素を格納するのは元のseqrに影響を与えずその逆も真である。しかし新しいシーケンス内の要素はコピーではなく、元のシーケンスの要素と同一(eq
)になる。したがってコピーされたシーケンスを介して見つかった要素を変更するとオリジナルでも変更を見ることができる。
引数がテキストプロパティーをもつ文字列なら、コピー内のプロパティーリスト自身もコピーとなり、元のシーケンスのプロパティーリストと共有はされない。しかしプロパティーリストの実際の値は共有される。テキストのプロパティを参照のこと。
この関数はドットリストでは機能しない。循環リストのコピーは無限ループを起こすだろう。
シーケンスをコピーする別の方法についてはコンスセルおよびリストの構築のappend
、文字列の作成のconcat
、ベクターのための関数のvconcat
も参照されたい。
(setq bar (list 1 2)) ⇒ (1 2)
(setq x (vector 'foo bar)) ⇒ [foo (1 2)]
(setq y (copy-sequence x)) ⇒ [foo (1 2)]
(eq x y) ⇒ nil
(equal x y) ⇒ t
(eq (elt x 1) (elt y 1)) ⇒ t
;; 一方のシーケンスの要素を置き換え
(aset x 0 'quux)
x ⇒ [quux (1 2)]
y ⇒ [foo (1 2)]
;; 共有された要素の内部を変更
(setcar (aref x 1) 69)
x ⇒ [quux (69 2)]
y ⇒ [foo (69 2)]
この関数はsequenceの要素を反転した要素をもつ新たなシーケンスを作成する。元となる引数sequenceは変更されない。文字テーブルは反転できないことに注意。
(setq x '(1 2 3 4)) ⇒ (1 2 3 4)
(reverse x) ⇒ (4 3 2 1) x ⇒ (1 2 3 4)
(setq x [1 2 3 4]) ⇒ [1 2 3 4]
(reverse x) ⇒ [4 3 2 1] x ⇒ [1 2 3 4]
(setq x "xyzzy") ⇒ "xyzzy"
(reverse x) ⇒ "yzzyx" x ⇒ "xyzzy"
この関数はsequenceの要素を反転する。reverse
とは異なり、元となるsequenceは変更されるかもしれない。
たとえば:
(setq x (list 'a 'b 'c)) ⇒ (a b c)
x ⇒ (a b c) (nreverse x) ⇒ (c b a)
;; 先頭にあったコンスセルが末尾となった
x
⇒ (a)
混乱しないように、通常は元となるリストを保持する同じ変数に、nreverse
の結果を書き戻す:
(setq x (nreverse x))
お馴染の例(a b c)
のnreverse
を以下に図示する:
Original list head: Reversed list: ------------- ------------- ------------ | car | cdr | | car | cdr | | car | cdr | | a | nil |<-- | b | o |<-- | c | o | | | | | | | | | | | | | | ------------- | --------- | - | -------- | - | | | | ------------- ------------
setqが不要なのでベクターはより単純になる:
(setq x (copy-sequence [1 2 3 4])) ⇒ [1 2 3 4] (nreverse x) ⇒ [4 3 2 1] x ⇒ [4 3 2 1]
reverse
とは異なり、この関数は文字列では機能しない。aset
を使用して文字列データを変更できても、たとえmutableであったとしても文字列は不変として扱うことを強く推奨する。可変性を参照のこと。
この関数はsequenceを安定ソートする。この関数はすべてのシーケンスにたいしては機能せず、リストとベクターにたいしてのみ使用できることに注意されたい。sequenceがリストなら破壊的に変更される。この関数はソートされたsequenceをリターンして、要素の比較にはpredicateを使用する。安定ソートでは、ソートキーが等しい要素の相対順序がソートの前後で保たれる。この安定性は異なる条件により要素を並べ替えるために、連続してソートを行う場合に重要となる。
引数predicateは2つの引数を受け取る関数でなければならない。これはsequenceの2つの要素で呼び出される。昇順でソートするなら、1つ目の要素が2つ目の要素より“小”なら非nil
、それ以外ならnil
をリターンすること。
比較関数predicateは、少なくともsort
の単一の呼び出しにおいて、与えられた任意の引数ペアにたいして信頼できる結果をリターンしなければならない。これは非対照的(antisymmetric)、すなわちaがbより小なら、bがaより小であってはならず、推移律(transitive)、すなわちaがbより小、かつbがcより小なら、aはcより小でなければならない。これらの要件に合致しない比較関数を使用すると、sort
の結果は予想できない。
sort
のリストにたいする破壊的側面は、CDRを変更することによりsequenceを形成するコンスセルを再配置することにある。非破壊ソート関数は、それらのソート順に要素を格納するために、新たなコンスセルを作成するだろう。オリジナルを破壊せずにソートしたコピーを望むなら、まずcopy-sequence
でコピーしてからソートすること。
ソートによりsequenceのコンスセルのCARは変化しない。元々sequence内で要素a
を含むコンスセルは、ソート後もそのCARにa
を保持する。しかしCDRの変更により、ソート後には異なる位置に出現する。たとえば:
(setq nums (list 1 3 2 6 5 4 0)) ⇒ (1 3 2 6 5 4 0)
(sort nums #'<) ⇒ (0 1 2 3 4 5 6)
nums ⇒ (1 2 3 4 5 6)
警告
nums
内のリストが0を含まないことに注意。これはソート前と同じコンスセルだがもはやリストの先頭ではない。ソート前に引数を保持していた変数がソート済みリスト全体を保持すると仮定してはならない!
かわりにsort
の結果を保存して、それを使うこと。ほとんどの場合、わたしたちは元のリストを保持していた変数に結果を書き戻すようにしている。
(setq nums (sort nums #'<))
安定ソートの何たるかをより理解するには、以下のベクターのサンプルを考えてみよ。ソート後、car
が8であるようなすべてのアイテムはvector
の先頭にグループ化されるが、それらの相対的な順序は保たれる。car
が9であるようなすべてのアイテムはvector
の末尾にグループ化されるが、それらの相対的な順序も保たれる。
(setq vector (vector '(8 . "xxx") '(9 . "aaa") '(8 . "bbb") '(9 . "zzz") '(9 . "ppp") '(8 . "ttt") '(8 . "eee") '(9 . "fff"))) ⇒ [(8 . "xxx") (9 . "aaa") (8 . "bbb") (9 . "zzz") (9 . "ppp") (8 . "ttt") (8 . "eee") (9 . "fff")]
(sort vector (lambda (x y) (< (car x) (car y)))) ⇒ [(8 . "xxx") (8 . "bbb") (8 . "ttt") (8 . "eee") (9 . "aaa") (9 . "zzz") (9 . "ppp") (9 . "fff")]
ソートを行う他の関数についてはテキストのソートを参照のこと。sort
の有用な例は、ドキュメント文字列へのアクセスのdocumentation
を参照されたい。
seq.elライブラリーは、以下のようなプレフィクスseq-
がついたシーケンス操作用の追加のマクロと関数を提供します。これらを使うには、まずseqライブラリーをロードしなければなりません。
このライブラリー内で定義されたすべての関数は、副作用をもちません。これらは引数として渡されたすべてのシーケンス(リスト、ベクター、文字列)を変更しません。特に明記しなければ、結果は入力と同じ型のシーケンスです。述語を受け取る関数では、それらは単一の関数である必要があります。
seq.elライブラリーは、シーケンシャルなデータ構造の追加型で機能するように拡張可能です。そのためにすべての関数はcl-defgeneric
を使用して定義されています。cl-defgeneric
を使用した拡張の追加に関する詳細は、ジェネリック関数を参照してください。
この関数はindex(有効な範囲は0からsequenceの長さより1少ない整数)で指定されたsequenceの要素をリターンする。ビルトインのシーケンス型にたいする範囲外(out-of-range)の値にたいして、seq-elt
はelt
と同様に振る舞う。詳細はDefinition of eltを参照のこと。
(seq-elt [1 2 3 4] 2) ⇒ 3
seq-elt
はsetf
を使用してセット可能なplaceをリターンする(setf
マクロを参照)。
(setq vec [1 2 3 4]) (setf (seq-elt vec 2) 5) vec ⇒ [1 2 5 4]
この関数はsequence内の要素の個数をリターンする。ビルトインのシーケンス型にたいしてseq-length
はlength
と同様に振る舞う。Definition of lengthを参照のこと。
この関数はobjectがシーケンス(リストか配列)、またはseq.elのジェネリック関数を通じて定義されたすべての追加シーケンス型なら非nil
をリターンする。これはsequencep
の拡張された変種である。
(seqp [1 2]) ⇒ t
(seqp 2) ⇒ nil
この関数はsequenceの最初のn個(整数)を除く、すべての要素をリターンする.nが0以下なら結果はsequence。
(seq-drop [1 2 3 4 5 6] 3) ⇒ [4 5 6]
(seq-drop "hello world" -4) ⇒ "hello world"
この関数はsequenceの最初のn個(整数)の要素をリターンする。nが0以下なら結果はnil
。
(seq-take '(1 2 3 4) 3) ⇒ (1 2 3)
(seq-take [1 2 3 4] 0) ⇒ []
この関数はsequenceのメンバーを順にリターンし、predicateが最初にnil
をリターンした要素の前で停止する。
(seq-take-while (lambda (elt) (> elt 0)) '(1 2 3 -1 -2)) ⇒ (1 2 3)
(seq-take-while (lambda (elt) (> elt 0)) [-1 4 6]) ⇒ []
この関数はpredicateが最初にnil
をリターンした要素から、sequenceのメンバーを順にリターンする。
(seq-drop-while (lambda (elt) (> elt 0)) '(1 2 3 -1 -2)) ⇒ (-1 -2)
(seq-drop-while (lambda (elt) (< elt 0)) [1 4 6]) ⇒ [1 4 6]
この関数はsequenceの各要素にたいして、(恐らくは副作用を得るために)順番にfunctionを適用して、sequenceをリターンする。
この関数はsequenceの各要素にfunctionを適用した結果をリターンする。リターン値はリスト。
(seq-map #'1+ '(2 4 6)) ⇒ (3 5 7)
(seq-map #'symbol-name [foo bar]) ⇒ ("foo" "bar")
この関数はsequenceの各要素およびseqであるようなインデックスにfunctionを適用した結果をリターンする。リターン値はリスト。
(seq-map-indexed (lambda (elt idx) (list idx elt)) '(a b c)) ⇒ ((0 a) (1 b) (2 c))
この関数はsequencesの各要素にfunctionを適用した結果をリターンする。 functionのarity (関数が受け取れる引数の個数。subr-arityを参照)はシーケンスの個数にマッチしなければならない。マッピングは最短のシーケンス終端で停止する。リターン値はリスト。
(seq-mapn #'+ '(2 4 6) '(20 40 60)) ⇒ (22 44 66)
(seq-mapn #'concat '("moskito" "bite") ["bee" "sting"]) ⇒ ("moskitobee" "bitesting")
この関数はpredicateが非nil
をリターンしたsequence内のすべての要素のリストをリターンする。
(seq-filter (lambda (elt) (> elt 0)) [1 -1 3 -3 5]) ⇒ (1 3 5)
(seq-filter (lambda (elt) (> elt 0)) '(-1 -3 -5)) ⇒ nil
この関数はpredicateがnil
をリターンしたsequence内のすべての要素のリストをリターンする。
(seq-remove (lambda (elt) (> elt 0)) [1 -1 3 -3 5]) ⇒ (-1 -3)
(seq-remove (lambda (elt) (< elt 0)) '(-1 -3 -5)) ⇒ nil
この関数はinitial-valueとsequenceの1つ目の要素でfunctionを呼び出し、次にその結果とsequenceの2つ目の要素でfunctionを呼び出し、その次にその結果とsequenceの3つ目の要素で、...と呼び出した結果をリターンする。functionは引数が2つの関数であること。
functionは2つの引数で呼び出される。1つ目の引数としてintial-value (その後は累積値)、2つ目の引数としてsequence内の要素が使用される。
sequenceが空なら、functionを呼び出さずにinitial-valueをリターンする。
(seq-reduce #'+ [1 2 3 4] 0) ⇒ 10
(seq-reduce #'+ '(1 2 3 4) 5) ⇒ 15
(seq-reduce #'+ '() 3) ⇒ 3
この関数はsequenceの各要素に順にpredicateを適用してリターンされた、最初の非nil
値をリターンする。
(seq-some #'numberp ["abc" 1 nil]) ⇒ t
(seq-some #'numberp ["abc" "def"]) ⇒ nil
(seq-some #'null ["abc" 1 nil]) ⇒ t
(seq-some #'1+ [2 4 6]) ⇒ 3
この関数はpredicateが非nil
をリターンした、sequence内の最初の要素をリターンする。predicateにマッチする要素がなければ、この関数はdefaultをリターンする。
この関数は見つかった要素がdefaultと等しい場合、要素が見つかったかどうかを知る術がないので曖昧さをもつことに注意。
(seq-find #'numberp ["abc" 1 nil]) ⇒ 1
(seq-find #'numberp ["abc" "def"]) ⇒ nil
この関数はsequenceの各要素にpredicateを適用して、すべてが非nil
をリターンしたら非nil
をリターンする。
(seq-every-p #'numberp [2 4 6]) ⇒ t
(seq-every-p #'numberp [2 4 "6"]) ⇒ nil
この関数はsequenceが空ならnil
をリターンする。
(seq-empty-p "not empty") ⇒ nil
(seq-empty-p "") ⇒ t
この関数はsequence内でpredicateが非nil
をリターンした要素の個数をリターンする。
(seq-count (lambda (elt) (> elt 0)) [-1 2 0 3 -2]) ⇒ 2
この関数はfunctionに応じてソートされたsequenceのコピーをリターンする。functionは2つの引数を受け取り、1つ目の引数が2つ目より前にソートされるべきなら非nil
をリターンする。
この関数はseq-sort
と似ているがソート前にsequenceの要素にfunctionを適用して変換する点が異なる。functionは単一の引数を受け取る関数。
(seq-sort-by #'seq-length #'> ["a" "ab" "abc"]) ⇒ ["abc" "ab" "a"]
この関数はsequence内の少なくとも1つの要素がeltとequalなら非nil
をリターンする。オプション引数functionが非nil
なら、それはデフォルトのequal
のかわりに使用する2つの引数を受け取る関数であること。
(seq-contains-p '(symbol1 symbol2) 'symbol1) ⇒ t
(seq-contains-p '(symbol1 symbol2) 'symbol3) ⇒ nil
この関数は順序とは無関係にsequence1とsequence2が同じ要素を含むかどうかをチェックする。オプション引数testfnが非nil
なら、デフォルトのequal
のかわりに使用する2つの引数を受け取る関数であること。
(seq-set-equal-p '(a b c) '(c b a)) ⇒ t
(seq-set-equal-p '(a b c) '(c b)) ⇒ nil
(seq-set-equal-p '("a" "b" "c") '("c" "b" "a")) ⇒ t
(seq-set-equal-p '("a" "b" "c") '("c" "b" "a") #'eq) ⇒ nil
この関数はeltとequal
であるようなsequence内の最初の要素のインデックスをリターンする。オプション引数functionが非nil
なら、それはデフォルトのequal
のかわりに使用する2つの引数を受け取る関数であること。
(seq-position '(a b c) 'b) ⇒ 1
(seq-position '(a b c) 'd) ⇒ nil
この関数は重複を削除したsequenceの要素のリストをリターンする。オプション引数functionが非nil
なら、それはデフォルトのequal
のかわりに使用する2つの引数を受け取る関数であること。
(seq-uniq '(1 2 2 1 3)) ⇒ (1 2 3)
(seq-uniq '(1 2 2.0 1.0) #'=) ⇒ (1 2)
この関数はsequenceのstartからend(いずれも整数)までのサブセットをリターンする(endのデフォルトは最後の要素)。startかendが負ならsequenceの最後から数える。
(seq-subseq '(1 2 3 4 5) 1) ⇒ (2 3 4 5)
(seq-subseq '[1 2 3 4 5] 1 3) ⇒ [2 3]
(seq-subseq '[1 2 3 4 5] -3 -1) ⇒ [3 4]
この関数はsequencesを結合して作成されたtype型のシーケンスをリターンする。typeはvector
、list
、string
のいずれか。
(seq-concatenate 'list '(1 2) '(3 4) [5 6]) ⇒ (1 2 3 4 5 6)
(seq-concatenate 'string "Hello " "world") ⇒ "Hello world"
この関数はsequenceの各要素にfunctionを適用した結果に、seq-concatenate
を適用した結果をリターンする。結果はtype型のシーケンス、またはtypeがnil
ならリストである。
(seq-mapcat #'seq-reverse '((3 2 1) (6 5 4))) ⇒ (1 2 3 4 5 6)
この関数は長さnのサブシーケンスへグループ化したsequenceの要素のリストをリターンする。最後のシーケンスに含まれる要素はnより少ないかもしれない。nは整数であること。nが0以下の整数ならリターン値はnil
。
(seq-partition '(0 1 2 3 4 5 6 7) 3) ⇒ ((0 1 2) (3 4 5) (6 7))
この関数はsequence1とsequence2のいずれかに出現する要素のリストをリターンする。リターンされるリストの要素はすべて、2要素を比較してequalにならないという意味において一意である。オプション引数functionが非nil
なら、それはデフォルトのequal
のかわりに比較に使用する2つの引数を受け取る関数であること。
(seq-union [1 2 3] [3 5]) ⇒ (1 2 3 5)
この関数はsequence1とsequence2の両方に出現する要素のリストをリターンする。オプション引数functionが非nil
なら、それはデフォルトのequal
のかわりに比較に使用する2つの引数を受け取る関数であること。
(seq-intersection [2 3 4 5] [1 3 5 6 7]) ⇒ (3 5)
この関数はsequence1に出現するがsequence2に出現しない要素のリストをリターンする。オプション引数functionが非nil
なら、それはデフォルトのequal
のかわりに比較に使用する2つの引数を受け取る関数であること。
(seq-difference '(2 3 4 5) [1 3 5 6 7]) ⇒ (2 4)
この関数はsequenceの各要素にfunctionを適用して、その結果をキーとしてsequenceをalistに分割する。キーの比較にはequal
を使用する。
(seq-group-by #'integerp '(1 2.1 3 2 3.2)) ⇒ ((t 1 3 2) (nil 2.1 3.2))
(seq-group-by #'car '((a 1) (b 2) (a 3) (c 4))) ⇒ ((b (b 2)) (a (a 1) (a 3)) (c (c 4)))
この関数はシーケンスsequenceをtype型のシーケンスに変換する。typeはvector
、string
、list
のいずれかであること。
(seq-into [1 2 3] 'list) ⇒ (1 2 3)
(seq-into nil 'vector) ⇒ []
(seq-into "hello" 'vector) ⇒ [104 101 108 108 111]
この関数はsequenceの最小の要素をリターンする。sequenceの要素は数字かマーカー(マーカーを参照)でなければならない。
(seq-min [3 1 2]) ⇒ 1
(seq-min "Hello") ⇒ 72
この関数はsequenceの最大の要素をリターンする。sequenceの要素は数字かマーカーでなければならない。
(seq-max [1 3 2]) ⇒ 3
(seq-max "Hello") ⇒ 111
このマクロはdolist
(dolistを参照)と同様だが、sequenceにリスト、ベクター、文字列のいずれかを指定できる点が異なる。これ主な利点は副作用である。
このマクロはvar-sequence内で定義される変数にval-sequenceの対応する要素をバインドする。これは分割代入(destructuring binding)として知られている。var-sequenceの要素は、ネストされた非構造化を許容することにより自身にシーケンスを含むことができる。
var-sequenceシーケンスには、val-sequenceの残りにバインドされる変数名が後続するような&rest
マーカーを含めることもできる。
(seq-let [first second] [1 2 3 4] (list first second)) ⇒ (1 2)
(seq-let (_ a _ b) '(1 2 3 4) (list a b)) ⇒ (2 4)
(seq-let [a [b [c]]] [1 [2 [3]]] (list a b c)) ⇒ (1 2 3)
(seq-let [a b &rest others] [1 2 3 4] others)
⇒ [3 4]
pcase
パターンは分割代入にたいする代替えの機能を提供する。pcase
パターンによる分解を参照のこと。
このマクロはseq-let
と同様に機能するが、let
ではなくあたかもsetq
で値が変数にバインドされる点が異なる。
(let ((a nil) (b nil)) (seq-setq (_ a _ b) '(1 2 3 4)) (list a b)) ⇒ (2 4)
この関数はsequenceの要素をランダムにリターンする。
(seq-random-elt [1 2 3 4]) ⇒ 3 (seq-random-elt [1 2 3 4]) ⇒ 2 (seq-random-elt [1 2 3 4]) ⇒ 4 (seq-random-elt [1 2 3 4]) ⇒ 2 (seq-random-elt [1 2 3 4]) ⇒ 1
sequenceが空ならこの関数はエラーをシグナルする。
Next: 配列, Up: シーケンス、配列、ベクター [Contents][Index]