連想配列

本ページには広告が含まれています。

連想配列とは、自動的に割り当てられる数字をキーとして持つかわりに、自由に任意の文字列を割り振ることができる配列のことです。添え字に番号の代わりに名前をつけることでわかりやすく管理することができます。

構文
// 連想配列の宣言
HASHTBL 変数

// 大文字小文字を区別する(デフォルトは区別しない)
HASHTBL 変数 = HASH_CASECARE

// 順列で読出す時にキーはソートされている
HASHTBL 変数 = HASH_SORT

// キーにデータを代入
変数[キー] = データ

// キーが存在するか
変数[キー, HASH_EXISTS]

// キーを削除
変数[キー, HASH_REMOVE]

// 指定した順列番号のキーを取得
変数[順列番号, HASH_KEY]

// 指定した順列番号のデータを取得
変数[順列番号, HASH_VAL]

// 連想配列を削除
変数 = HASH_REMOVEALL

削除HASH_REMOVEは必要無くとも変数で受ける必要あり
引数
戻り値

連想配列とは

連想配列とはキーと値をペアに持つデータ構造のことで、キーを使用して値を取得することができます。

配列との違い

配列・連想配列ともに複数の値を格納できるデータ構造ですが、値を管理するための名前の付け方に違いがあります。

配列では0から始まる連番で値を管理する添え字を使うのに対し、連想配列では値それぞれに固有の名前をつけて管理することができます。この固有の名前のことをキーといい、その値が何を表しているのか理解しやすくなります。

以下は、各教科の点数を配列で書いたプログラムです。添え字の0から順に、国語・社会・数学・理科・英語の点数を入れて管理しています。

UWSC
DIM score[] = 62, 80, 85, 93, 79    // 国語、社会、数学、理科、英語

PRINT score[0]      // 国語
PRINT score[1]      // 社会
PRINT score[2]      // 数学
PRINT score[3]      // 理科
PRINT score[4]      // 英語

PRINT "合計点:" + CALCARRAY(score, CALC_ADD)
PRINT "平均点:" + CALCARRAY(score, CALC_AVR)

次に、以下は連想配列で書いた場合のプログラムです。連想配列のキー名を科目にすることでどの科目が何点なのかがわかりやすくなります。

配列で使えたCALCARRAY関数 (スクリプト関数)が連想配列では使えないというデメリットもありますが、要素をループをすることで合計点・平均点も求めることができます。

UWSC
HASHTBL score

score["国語"] = 62
score["社会"] = 80
score["数学"] = 85
score["理科"] = 93
score["英語"] = 79

PRINT score["国語"]
PRINT score["社会"]
PRINT score["数学"]
PRINT score["理科"]
PRINT score["英語"]

DIM sum = 0

FOR i = 0 TO LENGTH(score) - 1
	sum = sum + score[i, HASH_VAL]
NEXT

PRINT "合計点:" + sum
PRINT "平均点:" + (sum / LENGTH(score))

要素の追加

要素を追加するには以下のように記述し、要素を追加すると順列番号は0から順に1ずつ加算されていきます。

UWSC
連想配列名[キー名] = 値

配列との違いに出したプログラムでも要素の追加について記述していますが、以下のように追加する要素を記述していきます。

UWSC
HASHTBL score
 
score["国語"] = 62
score["社会"] = 80
score["数学"] = 85
score["理科"] = 93
score["英語"] = 79

すでに存在するキー名で追加した場合は、あとに書いた値で上書きされます。以下は数学の値が85から75に更新されます。

UWSC
HASHTBL score

score["国語"] = 62
score["社会"] = 80
score["数学"] = 85
score["理科"] = 93
score["英語"] = 79

score["数学"] = 75

要素の存在有無の確認

要素が存在するか確認するには以下のように記述します。存在する場合はTrue、存在しない場合にはFalseが返ります。

UWSC
連想配列名[キー名, HASH_EXISTS]

以下は要素が存在するか確認するプログラムです。score[理科]は存在するのでTruescore[音楽]は存在しないのでFalseが返ります。

UWSC
HASHTBL score

score["国語"] = 62
score["社会"] = 80
score["数学"] = 85
score["理科"] = 93
score["英語"] = 79

PRINT score["理科", HASH_EXISTS]
PRINT score["音楽", HASH_EXISTS]
結果
プレーンテキスト
True
False

HASH_EXISTSは戻り値を変数で受ける必要があり、以下のような書き方はSyntaxErrorが発生します。

UWSC
score["数学", HASH_EXISTS]

大抵の場合は指定したキー名が存在するかしないかの条件分岐で以下のどちらかの書き方になります。

UWSC
IF score["数学", HASH_EXISTS] THEN (存在するときの処理)
UWSC
IF !score["数学", HASH_EXISTS] THEN (存在しないときの処理)

キーを削除

連想配列のキーを削除するには以下のように記述します。キーを削除できた場合True、削除できなかった(存在しなかったなどの)場合はFalseが返ります。

UWSC
連想配列名[キー, HASH_REMOVE]

以下はキー名が理科の要素を削除するプログラムです。1回目は要素の削除に成功するのでTrue、2回目はすでに削除された要素なのでFalseを返します。

UWSC
HASHTBL score

score["国語"] = 62
score["社会"] = 80
score["数学"] = 85
score["理科"] = 93
score["英語"] = 79

PRINT score["理科", HASH_REMOVE]
PRINT score["理科", HASH_REMOVE]
結果
プレーンテキスト
True
False

キーを削除すると削除したキー以降の順列番号が詰められ連番を維持します。以下はキー名が理科の要素を削除したので順列番号が3以降の要素が詰められ、英語の順列番号が3になります。

UWSC
HASHTBL score

score["国語"] = 62
score["社会"] = 80
score["数学"] = 85
score["理科"] = 93
score["英語"] = 79

FOR i = 0 TO LENGTH(score) - 1
	PRINT i + "," + score[i, HASH_KEY] + "," + score[i, HASH_VAL]
NEXT

PRINT "-----"

PRINT score["理科", HASH_REMOVE]

PRINT "-----"

FOR i = 0 TO LENGTH(score) - 1
	PRINT i + "," + score[i, HASH_KEY] + "," + score[i, HASH_VAL]
NEXT
結果
プレーンテキスト
0,国語,62
1,社会,80
2,数学,85
3,理科,93
4,英語,79
-----
True
-----
0,国語,62
1,社会,80
2,数学,85
3,英語,79

HASH_REMOVEHASH_EXISTSと同様変数で受ける必要があり、以下のように記述するとエラーが発生します。

UWSC
score["数学", HASH_REMOVE]

結果を変数に代入するか画面やログに出力する必要があります。

UWSC
PRINT score["数学", HASH_REMOVE]

削除のみ行いたい場合は、FUKIDASI関数 (スクリプト関数)で表示することでエラーを回避することができます。

UWSC
FUKIDASI(score["数学", HASH_REMOVE])

順列番号からキー名を取得

順列番号からキー名を取得するには以下のように記述します。

UWSC
連想配列名[順列番号, HASH_KEY]

順列番号が2LENGTH(score)-1のキー名を取得します。

順列番号は0からなので2は3番目の数学を、LENGTH(score)-1は後ろから1番目の英語を返します。

UWSC
HASHTBL score

score["国語"] = 62
score["社会"] = 80
score["数学"] = 85
score["理科"] = 93
score["英語"] = 79

PRINT score[2, HASH_KEY]
PRINT score[LENGTH(score)-1, HASH_KEY]
結果
プレーンテキスト
数学
英語

順列番号からデータを取得

順列番号からデータを取得するには以下のように記述します。

UWSC
連想配列名[順列番号, HASH_VAL]

順列番号が2LENGTH(score)-1の値を取得します。

順列番号が2はキー名が数学の値である85LENGTH(score)-1はキー名が英語の値である79を返します。

UWSC
HASHTBL score

score["国語"] = 62
score["社会"] = 80
score["数学"] = 85
score["理科"] = 93
score["英語"] = 79

PRINT score[2, HASH_VAL]
PRINT score[LENGTH(score)-1, HASH_VAL]
結果
プレーンテキスト
85
79

連想配列をキー名でソートする

連想配列をキー名で昇順ソートするには連想配列宣言時にHASH_SORTを指定します。

UWSC
HASHTBL fruits = HASH_SORT OR HASH_CASECARE

fruits["apple"] = "りんご"
fruits["grape"] = "ぶどう"
fruits["cherry"] = "さくらんぼ"
fruits["peach"] = "もも"
fruits["banana"] = "バナナ"

PRINT fruits["Apple"]
PRINT fruits["grape"]
PRINT "----------"

FOR i=0 TO LENGTH(fruits)-1
	PRINT fruits[i, HASH_KEY]  + ":" + fruits[i, HASH_VAL]
NEXT
結果
CSV
apple:    りんご
banana:   バナナ
cherry:   さくらんぼ
grape:    ぶどう
peach:    もも

以下はFOR-IN-NEXTで書いた場合。

UWSC
HASHTBL fruits = HASH_SORT

fruits["apple"] = "りんご"
fruits["grape"] = "ぶどう"
fruits["cherry"] = "さくらんぼ"
fruits["peach"] = "もも"
fruits["banana"] = "バナナ"

FOR item IN fruits
	PRINT item + ":" + fruits[item]
NEXT
結果
CSV
apple:    りんご
banana:   バナナ
cherry:   さくらんぼ
grape:    ぶどう
peach:    もも

降順ソートは指定できないので、昇順ソートした配列をFOR文で後ろから要素を取得していきます。

UWSC
HASHTBL fruits = HASH_SORT OR HASH_CASECARE

fruits["apple"] = "りんご"
fruits["grape"] = "ぶどう"
fruits["cherry"] = "さくらんぼ"
fruits["peach"] = "もも"
fruits["banana"] = "バナナ"

FOR i=LENGTH(fruits)-1 TO 0 STEP -1
	PRINT fruits[i, HASH_KEY]  + ":" + fruits[i, HASH_VAL]
NEXT
結果
CSV
peach:    もも
grape:    ぶどう
cherry:   さくらんぼ
banana:   バナナ
apple:    りんご

連想配列のキーの大文字小文字の区別をする

キーの大文字と小文字を区別するには宣言時にHASH_CASECAREを指定します。指定したキーの大文字と小文字を区別するので、PRINT fruits["Apple"]ではりんごは出力されません。

UWSC
HASHTBL fruits = HASH_CASECARE

fruits["apple"] = "りんご"
fruits["grape"] = "ぶどう"
fruits["cherry"] = "さくらんぼ"
fruits["peach"] = "もも"
fruits["banana"] = "バナナ"

PRINT fruits["Apple"]
PRINT fruits["grape"]
結果
プレーンテキスト

ぶどう

連想配列のキーでソートし、かつ、大文字小文字を区別する

キーの大文字と小文字を区別し、さらにソートするには宣言時にHASH_SORT OR HASH_CASECAREを指定します。

UWSC
HASHTBL fruits = HASH_SORT OR HASH_CASECARE

fruits["apple"] = "りんご"
fruits["grape"] = "ぶどう"
fruits["cherry"] = "さくらんぼ"
fruits["peach"] = "もも"
fruits["banana"] = "バナナ"

PRINT fruits["Apple"]
PRINT fruits["grape"]
PRINT "----------"

FOR item IN fruits
	PRINT item + ":" + fruits[item]
NEXT
結果
CSV

ぶどう
----------
apple:        りんご
banana:       バナナ
cherry:       さくらんぼ
grape:        ぶどう
peach:        もも

連想配列のキー名と値を入れ替える

連想配列関数 (自作関数)を使い連想配列のキー名と値を入れ替えます。

UWSC
HASHTBL fruits

fruits["apple"] = "りんご"
fruits["grape"] = "ぶどう"
fruits["cherry"] = "さくらんぼ"
fruits["peach"] = "もも"
fruits["banana"] = "バナナ"

arrayFlip(fruits)

FOR n = 0 TO LENGTH(fruits) - 1
	PRINT fruits[n, HASH_KEY] + ":" + fruits[n, HASH_VAL]
NEXT

//////////////////////////////////////////////////
// 【引数】
//   associative : キーと値を入れ替える連想配列。参照引数。 
// 【戻り値】
//   
//////////////////////////////////////////////////
PROCEDURE arrayFlip(Var associative[])
    HASHTBL tmp
    FOR i = 0 TO LENGTH(associative)-1
        tmp[associative[i, HASH_VAL]] = associative[i, HASH_KEY]
    NEXT
    associative = HASH_REMOVEALL
    FOR i = 0 TO LENGTH(tmp)-1
        associative[tmp[i, HASH_KEY]] = tmp[i, HASH_VAL]
    NEXT
FEND
結果
CSV
りんご:       apple
ぶどう:       grape
さくらんぼ:   cherry
もも:         peach
バナナ:       banana

関連記事

CALCARRAY関数 (スクリプト関数)
配列の合計値・最小値・最大値・平均値を求めます。
GETALLWIN関数 (スクリプト関数)
全ウィンドウのIDを取得します。
GETOLEITEM関数 (スクリプト関数)
JOIN関数 (スクリプト関数)
引数に指定した配列を結合し文字列を返します。
SETCLEAR関数 (スクリプト関数)
配列のすべての要素を任意の値で埋めます。
SHIFTARRAY関数 (スクリプト関数)
配列を指定した値だけシフトします。プラス値で後方、マイナス値で前方にシフトします。
divisors関数 (自作関数)
引数に指定した数値の約数のリストを返します。
Collatz関数 (自作関数)
コラッツ数列 を求め結果を配列で返します。
LENGTH関数 (スクリプト関数)
POPUPMENU関数 (スクリプト関数)
ポップアップメニューを表示し、引数に指定した配列の中から選択された項目の要素番号を取得します。選択された項目を取得したい場合は、POPUPMENUの戻値を引数に指定した配列の要素番号として指定します。