検索エンジンから来た人に注意

このマニュアルは、Emacs ver. 19.x 向けのマニュアルを Mule 2.x の開発にあたり邦訳したものを、 電脳外道学会がミラーリングしているものであり、旧版製品パラノイアであるところの椅子人の趣味によるものです。

しかしながら、現在の Emacs の主流は ver. 20 以降であり、ver 19.x と ver 20.x とでは、仕様の違いが少なからずあります。

したがって、一般的な Emacs ユーザーにとっては、 このマニュアルと実機の動作とが符合しない場合があります。
特に、公開用の Emacs Lisp コードを書こうとする人は、 新バージョンのマニュアル(英語)を参照することを強くおすすめします。


トップページ&リンク | マニュアルの目次 | 検索
Go to the first, previous, next, last section, table of contents.


シーケンス、配列、ベクタ

シーケンス(sequence)型は、リスト、ベクタ、文字列というほかの三つの Lisp型の和集合であることを思い出してください。いいかえれば、任意のリストは シーケンスであり、任意のベクタはシーケンスであり、任意の文字列は シーケンスです。全てのシーケンスが共通してもつ性質は、順序づけられた要素の 集まりだということです。

配列(array)は、プリミティブなオブジェクトの一つで、要素ごとに スロットを持ちます。全ての要素は、一定の時間でアクセス可能ですが、 既存の配列の長さを変えることはできません。文字列とベクタは配列の 二つの型です。

リストは要素の並びですが、プリミティブなオブジェクトの一つ ではありません。リストはコンス・セルからなり、要素ごとに一つのセルが 割当てられています。n番目の要素を見つけるには、n番目の コンス・セルまで全て見なければならないので、リストの先頭から遠い要素ほど アクセスに時間がかかります。しかし、リストだと要素を追加することや 取り除くことができます。

次の図式は、これらの型の間の関係を示しています:

ベクタとリストの要素は、任意のLispオブジェクトで構いません。 文字列の要素は、全て文字です。

シーケンス

Emacs Lispでは、シーケンス(sequence)は、リスト、ベクタ、 文字列のいずれかです。全てのシーケンスが共通してもつ性質は、 順序づけられた要素の集まりだということです。 本節では、これらのシーケンスを受けつける関数を説明します。

Function: sequencep object
objectがリスト、ベクタ、文字列ならばtを、 そうでなければnilを返します。

Function: copy-sequence sequence
sequenceのコピーを返します。コピーは元のシーケンスと同じ型の オブジェクトで、同じ要素を同じ順序で持ちます。

コピーに新たな要素を格納しても、元のsequenceに影響しませんし、 その逆も同じです。けれども、作られた方のシーケンスの要素はコピーでは ありません。それらは元の要素と同一(eq)のものです。 したがって、コピーされたシーケンスでこれらの要素内に行なった変更は、 元のシーケンスでも見ることができます。

もしそのシーケンスがテキスト属性をもつ文字列であるならば、 コピーでの属性リスト自身もコピーであり、元の属性リストを共有するものでは ありません。けれども、属性の実際の値は共有されています。 See section テキスト属性

シーケンスをコピーするほかの方法については、 section コンス・セルとリストの生成append、 section 文字列の生成concat、 section ベクタvconcatなども参照してください。

(setq bar '(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

;; シーケンスの1要素を置き換える。
(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)]

Function: length sequence

sequence中の要素の個数を返します。sequenceがコンス・セルで あっても、(最後のCDRがnilではないので)それがリストではないならば、 wrong-type-argumentエラーが通知されます。

(length '(1 2 3))
    => 3
(length ())
    => 0
(length "foobar")
    => 6
(length [1 2 3])
    => 3

Function: elt sequence index
この関数は、sequenceの添字index番目の要素を返します。 正当なindexの値は整数で、範囲は0からsequenceの長さよりも 一つ小さい値までです。範囲外のindex値を指定すると、sequenceが リストのときはnilを返します。それ以外の場合は、 args-out-of-rangeエラーを発します。
(elt [1 2 3 4] 2)
     => 3
(elt '(1 2 3 4) 2)
     => 3
(char-to-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(see section 配列に関する関数)と nth(see section リストの要素の参照)とを一般化したものです。

配列

配列(array)オブジェクトは、スロットを持ち、そこにほかのLisp オブジェクトを複数、格納できます。それらを配列要素と呼びます。 任意の配列要素は一定の時間でアクセスできます。それに対しリストの要素は、 そのリスト内の位置に比例したアクセス時間を要します。

配列作成の際は、それがいくつ要素をもつかを指定しなければなりません。 割当てられる空間の大きさは要素数に依存します。したがって、いったん作成した 配列の大きさを変更することは不可能です。要素の追加や削除はできません。 しかし、要素を異なる値で置き換えることはできます。

Emacsは、ともに1次元である二つの配列型、文字列(string)ベクタ(vector)を定義しています。ベクタは一般化された配列です。 つまり、その要素は任意のLispオブジェクトで構いません。文字列は、 その要素として文字(即ち、0から255までの整数)だけが許される、 特化した配列です。いずれの配列型も固有のリード構文を持ちます。 section 文字列型と、See section ベクタ型

いずれの配列も次の特性を持ちます:

原則的には、テキスト文字の配列が欲しい場合、文字列あるいはベクタの どちらでも構いません。しかし、実用的には、そのような場合は常に文字列を 選んでいます。それには四つ理由があります:

対照的に、(キー・シーケンスなどの)キーボード入力文字の配列に対しては、 ベクタであることが必要な場合もあります。というのも、多くの キーボード入力文字は、文字列に収まるような範囲の外にあるためです。 See section キー・シーケンス入力

配列に関する関数

本節では、文字列とベクタを受けつける関数を説明します。

Function: arrayp object
この関数は、objectが配列(即ち、ベクタあるいは文字列)であるならば、 tを返します。
(arrayp [a])
=> t
(arrayp "asdf")
=> t

Function: aref array index
この関数は、arrayindex番目の要素を返します。 第1要素の添字は0です。
(setq primes [2 3 5 7 11 13])
     => [2 3 5 7 11 13]
(aref primes 4)
     => 11
(elt primes 4)
     => 11

(aref "abcdefg" 1)
     => 98           ; `b' は ASCII コード 98.

section シーケンスにある関数eltも参照してください。

Function: aset array index object
この関数は、arrayindex番目の要素にobjectを設定します。 この関数は、objectを返します。
(setq w [foo bar baz])
     => [foo bar baz]
(aset w 0 'fu)
     => fu
w
     => [fu bar baz]

(setq x "asdfasfd")
     => "asdfasfd"
(aset x 3 ?Z)
     => 90
x
     => "asdZasfd"

arrayが文字列なのにobjectが文字ではないならば、 結果はwrong-type-argumentエラーとなります。

Function: fillarray array object
この関数は、objectarrayを埋めます。その結果、arrayの 各要素はobjectとなります。この関数は、arrayを返します。
(setq a [a b c d e f g])
     => [a b c d e f g]
(fillarray a 0)
     => [0 0 0 0 0 0 0]
a
     => [0 0 0 0 0 0 0]
(setq s "When in the course")
     => "When in the course"
(fillarray s ?-)
     => "------------------"

arrayが文字列なのにobjectが文字ではないならば、結果は wrong-type-argumentエラーとなります。

シーケンス一般についての関数copy-sequencelengthは、 配列であろうオブジェクトに対してもしばしば有用です。 See section シーケンス

ベクタ

Lispにおける配列は、ほとんどの言語における配列同様、メモリの ひとかたまりからなり、要素には一定の時間でアクセスできます。 ベクタ(vector)は汎用の配列であり、その要素は任意のLispオブェクトで 構いません(これに対して、Emacs Lispでのほかの配列文字列(string)では、 その要素は文字でなければなりません)。ベクタはEmacs内で、 構文テーブル(整数のベクタ)として、obarray(シンボルのベクタ)として、 キーマップ(コマンドのベクタ)として使われています。 内部的にはさらに、バイトコンパイルされた関数表現の一部としても使われます。 そのような関数を印字すると、ベクタが中にあるのが見えます。

Emacs Lispでは、ベクタ要素の添字は0からはじまり、そこから順に数えて 行きます。

ベクタは要素を角括弧で囲んだものとして表示されます。よって、要素が シンボルa, b, aであるベクタは、[a b a]と 表示されます。Lispの入力でもベクタを同じように書くことができます。

ベクタは、文字列や数同様に、評価に際しては定数とみなされます。 その評価結果は同じベクタです。評価もされないし、ベクタの要素を調べることさえ されません。See section 自己評価型形式

次に、これらの原則の例を示します。

(setq avector [1 two '(three) "four" [five]])
     => [1 two (quote (three)) "four" [five]]
(eval avector)
     => [1 two (quote (three)) "four" [five]]
(eq avector (eval avector))
     => t

ベクタを操作する関数

ベクタに関係するいくつかの関数を挙げます:

Function: vectorp object
この関数は、objectがベクタならtを返します。
(vectorp [a])
     => t
(vectorp "asdf")
     => nil

Function: vector &rest objects
この関数は、引数objectsが要素になるようなベクタを作成し、返します。
(vector 'foo 23 [bar baz] "rats")
     => [foo 23 [bar baz] "rats"]
(vector)
     => []

Function: make-vector length object
この関数は、length個の要素からなる新しいベクタを返します。 各要素をobjectに初期化します。
(setq sleepy (make-vector 9 'Z))
     => [Z Z Z Z Z Z Z Z Z]

Function: vconcat &rest sequences
この関数は、sequencesの全要素を含む新しいベクタを返します。 引数sequencesはリストでもベクタでも文字列でも構いません。 sequencesが何も与えられない場合、空ベクタを返します。

この値は新たに構築されたベクタであり、既存のいかなるベクタにもeqでは ありません。

(setq a (vconcat '(A B C) '(D E F)))
     => [A B C D E F]
(eq a (vconcat a))
     => nil
(vconcat)
     => []
(vconcat [A B C] "aa" '(foo (6 7)))
     => [A B C 97 97 foo (6 7)]

関数vconcatもまた、引数として整数を許します。引数をその整数の 10進印字表現をなす数字文字列に変換し、それを元の整数の代わりに使用します。 この機能は削除する予定なので、使ってはなりません。すでにこの機能を 使っているならば、直ちにプログラムを変更してください!こういった方法で整数を 数字に変換したいならば、format(see section 文字列の書式変換) あるいはnumber-to-string(see section 文字と文字列間の変換)を使ってください。

これ以外の結合用関数については、section マッピング関数にあるmapconcat、 section 文字列の生成にあるconcat、section コンス・セルとリストの生成にある appendを参照してください。

append関数でベクタを同じ要素をもつリストに変換する方法があります (see section コンス・セルとリストの生成):

(setq avector [1 two (quote (three)) "four" [five]])
     => [1 two (quote (three)) "four" [five]]
(append avector nil)
     => (1 two (quote (three)) "four" [five])


Go to the first, previous, next, last section, table of contents.