ハッシュ(Tc600-3以降)¶
Tc600-3 以降では、値の型にハッシュ(連想配列)が加わった。
ハッシュの値やキーには、配列やハッシュを入れられる(入れ子)。入れ子の読み書きや多次元代入は 値の入れ子と多次元代入 を参照。
500 系からの互換性に関わる変更は 600 での変更点 を参照。
生成¶
ハッシュは IHASH で作る。キーと値を交互に並べる。IHASH() は空のハッシュになる。
_h = IHASH("name", "さくら", "age", 16)
_e = IHASH()
文字列から作るときは HASH_SPLIT を使う。
_h = HASH_SPLIT("a=1,b=2", ",", "=")
ハッシュの変数は、IHASH などで最初にハッシュとして作っておく必要がある。未定義の変数に _x["a"] = 1 と書いても、ハッシュではなく汎用配列の扱いになる("a" は数値として 0 番目と解釈される)。
要素の参照・代入¶
h[キー] で値を読み、h[キー] = 値 で追加・上書きする。
_h = IHASH()
_h["name"] = "さくら"
_h["name"] // "さくら"
_h["none"] // VOID (キーが無いときは未定義の変数と同じ)
_h["age"] += 1 // 複合代入も使える
- キーが無いときは、未定義の変数と同じく VOID を返す(Tc603-1以降。Tc602-13 までは空文字列だった)。文字列としては空文字列、数値としては 0 として扱われるので、
_h["none"] == ""は 1、_h["none"] + 1は整数の 1 になる(範囲外の要素) - 複合代入(
+=-=*=/=%=)の左辺のキーが無いときも VOID として計算する(Tc602-10以降)。_count[_name] += 1で数を数えられる。キーがあって値が空文字列のときは、これまでどおり空文字列として計算する("" + 1は"1") - 「キーが無い」と「値が空文字列や VOID」を区別するときは HASH_EXIST を使う
- 値には配列やハッシュも入れられる(入れ子)
- 序数の2番目以降(範囲指定やデリミタ)は無視される。範囲つきの読み出し
h[a, b]は空文字列になる
キーの一致¶
スカラーのキーは「数値」と「文字列」に分けて比べる。
- 数値として扱うもの: 整数、実数、正規形の整数を表す文字列(
"9"、"-3"など)"09"、"-0"、"+1"、" 1"、64bit に収まらない数字列は文字列として扱う
- 数値同士は値で比べる。整数と実数も誤差なく比べる
- 文字列同士は文字列として比べる。VOID は空文字列と同じキーになる
このため、h[1]、h["1"]、h[1.0] はすべて同じキーになる。一方、h[1.5] と h["1.5"]、h[0] と h["-0"] は別のキーになる。
同じキーとみなされる値を複数回 IHASH に渡したときは、最初のキーと値が残る。
IHASH(9, "i9", "9", "s9") // 9=i9 だけ
並び順¶
ハッシュの要素はキーの順に並ぶ。挿入した順ではない。HASH_KEYS、HASH_VALUES、文字列化、foreach、セーブファイルの並びはすべてこの順になる。
- 数値 < 文字列 の順に並ぶ。数値同士は値の順、文字列同士は文字列の順
- キーが配列やハッシュのときは、スカラー < 配列 < ハッシュ の順に並び、配列同士・ハッシュ同士は先頭の要素から順に比べる
_h = IHASH(10,1, 9,1, 100,1, -1,1, "b",1, "B",1, 2.5,1)
HASH_KEYS(_h) // -1,2.5,9,10,100,B,b
値としての振る舞い¶
| 操作 | 結果 |
|---|---|
| 真偽 | 要素が1つ以上あれば真、空なら偽 |
GETTYPE / GETTYPEEX |
5 |
文字列化(TOSTR や文字列との連結) |
キー=値 を , でつないだもの。例 a=1,b=x |
| 数値化 | 0 |
h1 == h2 |
要素数、キー、値がすべて一致すれば真。値が入れ子なら中身まで比べる |
ハッシュとハッシュ以外の == |
常に偽(文字列化した結果が同じでも偽) |
+(相手がスカラーかハッシュ) |
両方を文字列にして連結する |
+(相手が配列) |
配列の要素ごとに、ハッシュと文字列として連結する |
- * / % |
警告 W0024 を出す(下記) |
_h = IHASH("a", 1)
_h + 1 // "a=11"
'z' + _h // "za=1"
_h + _h // "a=1a=1"
(1,2) + _h // ("1a=1","2a=1")
- * / %(複合代入を含む)の両辺のどちらかがハッシュのときは、警告 W0024 を出す。結果は、相手がスカラーなら右辺がそのまま返り(h - 1 は 1、1 * h は h)、相手が配列なら要素ごとに計算される。意味のある結果にはならないので使わないこと。なお、配列の要素がハッシュの場合((h, 1) - 1)は W0024 は出ない。
関数の引数と , 演算子¶
汎用配列は引数や , 演算子で展開されるが、ハッシュは展開されず、そのまま1つの要素になる。
_a = (0, _h, 2) // 要素数 3。_a[1] はハッシュ
func(_h) // func の中で _argv[0] がハッシュになる
foreach¶
ハッシュも foreach で回せる。1変数の形では、値がキーの順に入る。
_h = IHASH("a", 1, "b", 2)
foreach _h ; _v
{
// _v = 1, 2
}
変数を2つ書くと、1つ目にキー、2つ目に値が入る。この形は配列と簡易配列でも使え、1つ目には 0 から始まるインデックスが入る。
foreach _h ; _k, _v { _s += _k + '=' + _v + ' ' } // "a=1 b=2 "
foreach ("p", "q") ; _i, _v { ... } // _i = 0, 1
foreach "x,y" ; _i, _v { ... } // 簡易配列も同じ
詳細は フロー制御 を参照。