前回の投稿から 4 ヶ月も経ってしまいましたが、引き続き J のデータ型の解説をします。(あまり重要な機能ではないので、流し読みしても構いません。)
復習: 文字列はリスト
文字列は実際には文字のリストなので、=
の代わりに -:
を使うなど、扱いに注意が必要です。
'text' = 'text'
1 1 1 1
'text' -: 'text'
1
そこで、文字列を一つの値として扱いたい場合は、ボックス (<
) を使います。
(<'text') = <'text'
1
ほとんどの場合、この方法で十分ですが、特定の場面で役に立つデータ型があります。
シンボル
前置きが長くなりましたが、シンボル (symbol) は、一意な文字列を表すデータ型です。
シンボルを作るには s:
(monad) を使います。
a=: s:(<'text')
a
`text
datatype a
symbol
引数はボックス化した文字列です。注意してください。
シンボルは前に `
を付けて表示されますが、実際の値には `
は含まれません。
シンボルは文字列と同様に、どんな文字でも使うことができます。
s:<'`J 言語'''
``J 言語'
シンボルと文字列
シンボルと文字列は、datatype の結果からも分かるように、異なる種類の値として扱われます。
NB. 元の文字列と比較
a = <'text'
0
連結したり、文字を取り出したりすることもできません。
a,'b'
|domain error
| a ,'b'
1 { a
|index error
| 1 {a
シンボルは「文字の配列」ではなく、「文字列を表す定数」という役割なので、このような制約があります。
シンボルのリスト
シンボルは配列ではないので、異なる長さのシンボルをリストにすることができます。
s:'abcde' ; 'abc' ; '1234'
`abcde `abc `1234
s:
の引数を(ボックス化していない)文字列にすると、シンボルのリストを簡単に作れます。
s:' abcde abc 1234'
`abcde `abc `1234
s:'/abcde/abc/1234' NB. 上と同じ
`abcde `abc `1234
1 バイト目が区切り文字として解釈されることに注意してください。区切り文字には (ASCIIの範囲内で) どんな文字でも使えます 1。
シンボルの特徴
s:
で作ったシンボルの情報は、global symbol table (GST) という辞書に保存されます。シンボルの実体はGST のインデックス (一意な数値) です。次に同じ文字列からシンボルを作る時には、GST を参照して同じインデックスが返されます。
シンボルの実体が数値であることにより、シンボルの比較は文字列と比べて高速に行えます。また、同じ値を繰り返し使う場合、メモリの節約にもなります。
一方、GST は名前の通りグローバルなデータなので、プログラム全体で共有されます。また、GST に保存した情報を削除することはできません。そのため、大量のシンボルを生成することは避けるべきです。
用途
シンボルは以下の条件を満たす場合に使うと良いでしょう。
- 同じ文字列を繰り返し使う
- 比較を頻繫に行う
- 使う文字列の種類が限られていて、途中で変わることがない
具体的な例としては、他の言語の列挙体 (enum) のようなものが考えられますが、数値の定数を使う方が手っ取り早いので、あまり使われていないように思います 2。
[ 前 : ユニコード文字列 ] [ 目次 ] [ 次 : 疎行列 ]