連想配列(マップ/ハッシュ/ディクショナリ)の概要 2021/01/29
連想配列(マップ/ハッシュ/ディクショナリ)はキーと値の2つのオブジェクトのペアを複数保持し、キーからオブジェクトを取得できるコンテナオブジェクト。連想配列、マップ、ディクショナリなど、言語によって呼び方は違う。
配列が数字を添字とするものに対し、連想配列は任意のオブジェクトを添字にできる。任意といっても添字(キー)にできるオブジェクトには制限のある言語もある。
静的な型の言語では、キーと値はそれぞれすべて同じ型である必要がある。キーと値の型は違っていてもよい。
Java 2015/03/09
java.util.Map
インターフェースがあり、それを実装したクラスとして、java.util.HashMap
, java.util.LinkedHashMap
などがある。
java.util.Map
のインスタンスを生成したり、要素にアクセスしたりする言語構造ではなく、new
演算子を使ったり、メソッドを使ったりする。
インスタンス生成の例
import java.util.HashMap;
HashMap<String, Integer> map = new HashMap<String, Integer>();
map.put("a", 1);
map.put("b", 2);
空の java.util.Map
インスタンスを作るには
Collections.<String, Integer>emptyMap()
要素が1つだけの java.util.Map
インスタンスを作るには
Collections.<String, Integer>singletonMap(key, value)
要素を参照するには get
を使う。-> キーで値を参照するには
map.get("a");
LRUキャッシュを実装するには java.util.LinkedHashMap
が便利。java.util.LinkedHashMap
を継承するクラスを作って、removeEldestEntry
をオーバーライドすればよい。
なお、java.util.HashMap
などは複数のスレッドから同時に読み書きがあった場合に一貫性を保てなかったり、無限ループになってしまったりするので、synchronized
文や、java.util.concurrent.ConcurrentHashMap
を使うことを検討すべきである。
Scala 2015/03/21
Javaのクラスライブラリでサポートされている java.util.Map
インターフェースやその実装クラスのほかに、Scalaのコレクションフレームワークとして scala.collection.Map
トレイトがある。
Map
には不変(イミュータブル)なものと可変(ミュータブル)なものがあるが、scala.Predef.Map
が scala.collection.immutable.Map
の別名として定義されているため、なにもimport
せずに Map
として参照すると不変な Map
になる。
Map
のインスタンス生成の例
val map = Map("a" -> 1, "b" -> 2);
これは以下のシンタックスシュガー。
val map = scala.collection.immutable.Map.apply(scala.Predef.any2ArrowAssoc("a").`->`(1),
scala.Predef.any2ArrowAssoc("b").`->`(2));
PHP 2014/01/29
連想配列が組み込み型として存在する。連想配列のキーに整数を使えば、単純な配列として使うことができ、連想配列と通常の配列の区別がない。
連想配列を生成する例
$map = array('a' => 1, 'b' => 2, );
普通の配列と同様に最後に余計なカンマがあってもなくてもよい。
PHP 5.4からは以下のようにも書ける。
$map = ['a' => 1, 'b' => 2];
この構文でも最後に余計なカンマがあってもよい。
要素を参照するには []
を使う。
$map['a']
キーには以下のような制限がある。
- 浮動小数点数は整数に切り捨てられてしまう
- 整数と文字列は区別されない
TRUE
は1
になってしまうFALSE
は0
になってしまうNULL
は""
になってしまう- 配列やオブジェクトはキーとして使えない
Python 2015/09/14
ディクショナリ(辞書)というデータ型がある。
キーにはイミュータブル(不変)なオブジェクトであればなんでもよいので、タプルもキーに使える。
ディクショナリ自体はミュータブル(可変)である。
# ディクショナリの例
dic = {'a': 1, 'b': 2}
# dict関数に2要素のタプルの配列を与えてもよい
dict([('a', 1), ('b', 2)])
# 空のディクショナリ
dic = {}
# 空のディクショナリはdict関数に引数を与えないことでも作れる
dic = dict()
要素を参照するには []
を使う。
dic['a']
Ruby 2021/01/29
Hash
というハッシュテーブルのクラスが存在する。ハッシュテーブルは {}
で表すことができる。
hash = {'a' => 1, 'b' => 2}
Perlと同じく、=>
の代わりに ,
でキーと値を区切ってもよいらしい。
最後に余計なカンマがあっても問題ない。
hash = {
'a' => 1,
'b' => 2,
}
p hash
# => {"a"=>1, "b"=>2}
シンボルをキーにする場合、
hash = {:a => 1, :b => 2}
になるが、次のようにも書ける。
hash = {a: 1, b: 2}
# または
hash = {"a": 1, "b": 2}
# 後者の書き方であってもキーは文字列ではなくシンボルになる
要素を参照するには []
を使う。-> キーで値を参照するには
hash['a']
Rubyのハッシュは順序を保存する。キーが追加された順序で列挙される。
Perl
ハッシュ 2015/01/07
Perlではハッシュという。ハッシュの値にはスカラ(文字列、数字、レファレンスなど)しか含められないので、配列やハッシュ自体を値として持たせるには、レファレンスにする必要がある。
ハッシュを入れる変数は名前が %
で始まり、要素を参照するには $
で始める。%
や $
をシジル(sigil)と言う。
ハッシュの変数に要素数が偶数個のリストを代入すると、それがハッシュになる。以下の2つはまったく同じ意味で、どちらもハッシュを %hash
に代入している。
my %hash = (a => 1, b => 2);
my %hash = ('a', 1, 'b', 2);
上記のカッコで囲む表記をリストという。
リストの中の =>
は ,
とまったく同じ意味で、以下のように書いても差支えない。こんな書き方は普通はしないが。
my %hash = ('a', 1 => 'b', 2);
=>
はファットカンマと呼ばれるらしい。
=>
と ,
はまったく同じとはいえ、=>
の左にシングルクオートやダブルクオートで囲まれていないシンボルのようなものを書くと文字列の扱いになる、という仕様は ,
にはない。
最後に余計なカンマがあっても問題ない。
my %hash = (
a => 1,
b => 2,
);
ハッシュ %var
とスカラ変数 $var
は名前の衝突をせず共存できるのだが、普通はコードがわかりづらくなるのでそんなことはしない。
要素を参照するには変数名を $
で始めて、{}
を使う。-> キーで値を参照するには
$hash{a}
ハッシュへのレファレンス 2015/01/07
リスト表記の ()
の代わりに {}
を使うと、ハッシュへのレファレンスを直接書くことができる。
my $hash = {a => 1, b => 2};
これは以下と同じ。
my %h = (a => 1, b => 2);
my $hash = \%h;
ハッシュへのレファレンスはスカラなので、これ自体を別のハッシュや配列の要素にすることもできる。
レファレンスの実体を取り出すには、%$hash
のように頭に %
を付ける。
要素を参照するにはいったんハッシュの実体を取り出してからでもいいが、->{}
を使うとレファレンスから要素を直接参照することができる。 -> キーで値を参照するには
$hash->{a}
JavaScript 2013/11/01
オブジェクトがそのまま連想配列のように使える。JavaScriptにおいてオブジェクトと連想配列は同じで、下の2つは同じオブジェクトを生成する。
map = {a: 1, b: 2}
map = {'a': 1, 'b': 2}
最後に余計なカンマがあっても問題ない。
map = {'a': 1, 'b': 2, }
JSON 2013/10/20
JSONフォーマットは、JavaScriptでのオブジェクトの書き方に準ずるがJSONフォーマットのほうがルールが厳しい。
JavaScriptのオブジェクトの表記は、ほぼそのままJSONの表記となるが、少し違う点がある。
- キーは文字列のみで、必ずダブルクオーテーションで囲む
- 文字列は
"
で囲み、'
で囲むのは禁止 - 正数であっても先頭に
+
を付けるのは禁止 0.
で始まる浮動小数点数は許されるが、先頭の0
を省略した表記は禁止0
で始まる8進数表記や0x
で始まる16進数表記の数値は禁止- 文字列の中のエスケープシーケンスとして
\0
で始まる8進数表記や\x
で始まる16新数表記は禁止で、代わりに\u
で始まるUnicodeエスケープを使う。 undefined
やNaN
は禁止
その他にJSONパーサによっての制約もある。
- PHPのjson_decodeでは、要素の最後の余計なカンマがあるとパースできない -> JSONをPHPでデコードするには
CoffeeScript 2013/04/15
map = {a: 1, b: 2}
map = a: 1, b: 2
map =
a: 1
b: 2