連想配列
連想配列(れんそうはいれつ、英語: associative array)とは、コンピュータプログラミングにおいて、添え字にスカラー数値以外のデータ型(文字列型等)も使用できる配列である。抽象データ型のひとつ。連想リスト、連想コンテナ、辞書(あるいはカタカナでディクショナリ 英語: dictionary)、ハッシュ(英語: hash)、マップ(英語: map)とも呼ばれる。
歴史的には、最初に LISP の連想リストとして広く認知された。その後、SNOBOL で table
として、AWK で連想配列として実装したことで、その潜在能力がさらに広く知られるようになった。現在、Rubyなど一部の言語では、添え字にはどのようなデータでも使えるものもある。
概要
[編集]プログラミングにおける単純な配列は、特定のアドレスからのオフセット(ずれ)をインデックスとして、アドレスとオフセットによって目的の値を得る。これに対し連想配列では、要素とそれを紐付けできるような値(キーと呼ぶ)のペアで表され、キーによって目的の値を求める。辞書やディクショナリという呼び方は、要素を本文、キーを見出しになぞらえたものと言える。ハッシュという呼び名はハッシュテーブルによって実装されることによる。
データ構造
[編集]連想配列の実装に使われるデータ構造としては、主に平衡2分探索木(赤黒木やAVL木など)やハッシュテーブルがある。ほかにはB木や連想リスト、トライ木、基数木などが利用されることもある。純粋な連想配列においてはキーの重複があってはならない。マップ(連想配列)を拡張したマルチマップはキーが重複したデータも上書きせずに保持できるデータ構造である。
連想配列を一般化したデータ構造のひとつにマルチマップ(英語: multimap)があり、一つのキーに対して複数の値を格納することができる[1]。また別の一般化である双方向マップ(英語: bidirectional map、bidimap、double ordered map)はバインディング操作を双方向で行う(キーと値に全単射関係をもたせる)データコンテナである。双方向マップの値それぞれが重複のないキーに関連付けられなければならない。キーを引数に取る通常の連想配列におけるlookup操作の他に値を引数にとるlookup操作が追加され、この操作は引数として与えられた値に関連付けられたキーを検索する。
よく用意される命令
[編集]純粋な連想配列でのキー–値間の参照を束縛(またはバインディングとも)と呼ぶ。「束縛」という語は新たな参照を作る過程に対しても用いられる。
しばしば定義される操作は以下のようなものが挙げられる:[2][3]
- 追加・挿入
- 新しいキー–値対を配列に追加し、キーと値の間への新たな参照を生成する。この操作(を行なう関数)の引数はキーとそれに紐付くべき値である。
- 再配置・置換
- 既存のキー–値対の値を書き換え、キーからの古い参照を新たな値への参照に再生成する。引数は元のキーと新たな値である。
- 除去・削除
- キー–値対を配列から削除し、キーから値への参照を消去する。引数は配列から削除するキー。
- 検索・参照
- キーに束縛されている値を取り出す。引数はキーであり、キー束縛された値が戻り値となる。紐付いた値が見付からない場合に例外を投げる実装もある。
また、連想配列はここで上げた以外の操作も含む。それは例えばキーの束縛数を特定したりすべてのキーを調べるための反復子を作成したりといったものである。この反復子によって得られる参照の順序はしばしば不定となる。
連想配列を標準で提供する主な言語
[編集]- AWK —
greetings["en"] = "Hello"; greetings["fr"] = "Bonjour"
のような形式で宣言し,print greetings["fr"]
のように参照する[註 1][4]。 - GNU Bash —
declare -A greetings=(["en"]="Hello" ["fr"]="Bonjour")
のような形式で宣言し,echo ${greetings["fr"]}
のように参照する。[5] - C++ — 標準ライブラリのクラス
std::map
として提供されている —std::map<std::string, int, std::less<>> m;
。これはハッシュではなく二分木により実装されている。ハッシュを用いたstd::unordered_map
も提供される —std::unordered_map<std::string, int> um;
。 - D言語 —
int[string] b;
が、文字列をキーとして整数を値とする連想配列bの宣言である。 - ECMAScript (JavaScript) — すべてのObjectが、文字列あるいはシンボルをキーとする連想配列として扱われる。MapとWeakMap型だとキーを任意のオブジェクトにすることができる。
- Go —
map[string]int
が、文字列をキーとして整数を値とする連想配列の型定義である。 - Interactive Data Language
- korn
- Icon
- Java — Java Platform, Standard Edition標準パッケージの
,Map
,HashMap
,TreeMap
,LinkedHashMap
で提供。その他 Apache Commons Collections などでも提供。Hashtable
- LISP — 古典的にはキーとデータで構成された cons セル[6]のリスト、たとえば
(list (cons 'en "Hello") (cons 'fr "Bonjour"))
、を連想配列として利用した(car
部をキーにcdr
部をデータ、またはその逆)。これを便利に扱うための関数(assoc
,rassoc
)が提供されている。Common Lispにおいてはハッシュ関数を利用した連想配列が提供されており、make-hash-table
関数によってオブジェクトを生成でき、gethash
関数ととsetf
マクロの組み合わせによってキーと値のペアを操作できる。 - Lua — 表
tbl = {en = "Hello", fr = "Bonjour"}
として宣言し,print(tbl["idx1"])
のように参照する[7]。 - .NET Framework (C#,VB.NET,F#) -
System.Collections.Hashtable
,System.Collections.Specialized.ListDictionary
,System.Collections.Specialized.HybridDictionary
,System.Collections.Generic.Dictionary
にて提供。(ただしDictionary
は CLR 2.0 以降) - PL/SQL — 結合配列 (Oracle Database 9i 以降)
- PHP - 配列と連想配列の区別がない
- Python — 辞書
dict = {"en": "Hello", "fr": "Bonjour"}
として宣言し,print(dict["idx1"])
のように参照する[8]。 - Perl —
%
ではじまる変数が連想配列だが、個別の要素には$hash{$key}
で参照する。同言語で連想配列を(ハッシュ値を使うその実装方法にちなんで)「ハッシュ」と呼び始めたことから、「ハッシュ」が連想配列の別名として定着した。 - REXX
- Ruby — 組み込みのクラス
Hash
で提供 - Smalltalk
- SNOBOL
- Swift
- Visual Basic —
Scripting.Dictionary
で提供 - Visual Basic for Applications —
Scripting.Dictionary
で提供[9]
脚注
[編集]註釈
[編集]- ^ 実際には
BEGIN
アクションの内部などで行なう必要がある。
出典
[編集]- ^ Goodrich & Tamassia (2006), pp. 389–397.
- ^ Goodrich, Michael T.; Tamassia, Roberto (2006), “9.1 The Map Abstract Data Type”, Data Structures & Algorithms in Java (4th ed.), Wiley, pp. 368–371.
- ^ Mehlhorn, Kurt; Sanders, Peter (2008), “4 Hash Tables and Associative Arrays”, Algorithms and Data Structures: The Basic Toolbox, Springer, pp. 81–98.
- ^ “awk”. IEEE and The Open Group (2017年). 2018年11月2日閲覧。
- ^ “Bash Reference Manual: Arrays”. LFree Software Foundation, Inc. (2008年). 2018年11月2日閲覧。
- ^
car
,cdr
と呼ばれる二つデータが組になった、2-タプルのデータ構造 - ^ “Lua 5.3 Reference Manual”. Lua.org, PUC-Rio. (2018年). 2018年11月2日閲覧。
- ^ “5. データ構造 — Python 3.7.1 ドキュメント”. Python Software Foundation (2018年). 2018年11月2日閲覧。
- ^ “Dictionary オブジェクト”. Office デベロッパー センター (2019年4月2日). 2020年1月6日閲覧。