概要

連想配列(マップ/ハッシュ/ディクショナリ)はキーと値の2つのオブジェクトのペアを複数保持し、キーからオブジェクトを取得できるコンテナオブジェクト。連想配列、マップ、ディクショナリなど、言語によって呼び方は違う。

配列が数字を添字とするものに対し、連想配列は任意のオブジェクトを添字にできる。任意といっても添字(キー)にできるオブジェクトには制限のある言語もある。

静的な型の言語では、キーと値はそれぞれすべて同じ型である必要がある。キーと値の型は違っていてもよい。

Java

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

Javaのクラスライブラリでサポートされている java.util.Map インターフェースやその実装クラスのほかに、 Scalaのコレクションフレームワークとして scala.collection.Map トレイトがある。

Map には不変(イミュータブル)なものと可変(ミュータブル)なものがあるが、 scala.Predef.Mapscala.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

連想配列が組み込み型として存在する。連想配列のキーに整数を使えば、単純な配列として使うことができ、連想配列と通常の配列の区別がない。

連想配列を生成する例

$map = array('a' => 1, 'b' => 2, );

普通の配列と同様に最後に余計なカンマがあってもなくてもよい。

PHP 5.4からは以下のようにも書ける。

$map = ['a' => 1, 'b' => 2];

この構文でも最後に余計なカンマがあってもよい。

要素を参照するには [] を使う。

$map['a']

キーには以下のような制限がある。

配列 | PHP Manual
http://php.net/manual/ja/language.types.array.php

配列関係の関数 | PHP Manual
http://php.net/manual/ja/book.array.php

Python

ディクショナリ(辞書)というデータ型がある。

キーにはイミュータブル(不変)なオブジェクトであればなんでもよいので、 タプルもキーに使える。

ディクショナリ自体はミュータブル(可変)である。

# ディクショナリの例
dic = {'a': 1, 'b': 2}

# dict関数に2要素のタプルの配列を与えてもよい
dict([('a', 1), ('b', 2)])

# 空のディクショナリ
dic = {}

# 空のディクショナリはdict関数に引数を与えないことでも作れる
dic = dict()

要素を参照するには [] を使う。

dic['a']

Ruby

Hashというハッシュ(ハッシュテーブル)のクラスが存在する。ハッシュは {} で表すことができる。

hash = {'a' => 1, 'b' => 2}

Perlと同じく、=> の代わりに , でキーと値を区切ってもよいらしい。

最後に余計なカンマがあっても問題ない。

hash = {
  'a' => 1,
  'b' => 2,
}
p hash
# => {"a"=>1, "b"=>2}

要素を参照するには [] を使う。-> キーで値を参照するには

hash['a']

Hash | Ruby 2.1 リファレンスマニュアル
http://docs.ruby-lang.org/ja/2.1.0/class/Hash.html

Perl

ハッシュ

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}

ハッシュへのレファレンス

リスト表記の () の代わりに {} を使うと、ハッシュへのレファレンスを直接書くことができる。

my $hash = {a => 1, b => 2};

これは以下と同じ。

my %h = (a => 1, b => 2);
my $hash = \%h;

ハッシュへのレファレンスはスカラなので、これ自体を別のハッシュや配列の要素にすることもできる。

レファレンスの実体を取り出すには、%$hash のように頭に % を付ける。

要素を参照するにはいったんハッシュの実体を取り出してからでもいいが、 ->{} を使うとレファレンスから要素を直接参照することができる。 -> キーで値を参照するには

$hash->{a}

JavaScript

オブジェクトがそのまま連想配列のように使える。 JavaScriptにおいてオブジェクトと連想配列は同じで、下の2つは同じオブジェクトを生成する。

map = {a: 1, b: 2}
map = {'a': 1, 'b': 2}

最後に余計なカンマがあっても問題ない。

map = {'a': 1, 'b': 2, }

JSON

JSONフォーマットは、JavaScriptでのオブジェクトの書き方に準ずるが JSONフォーマットのほうがルールが厳しい。

JavaScriptのオブジェクトの表記は、ほぼそのままJSONの表記となるが、少し違う点がある。

その他にJSONパーサによっての制約もある。

CoffeeScript

map = {a: 1, b: 2}
map = a: 1, b: 2
map =
    a: 1
    b: 2
このサイトは筆者(hydrocul)の個人メモの集合です。すべてのページは永遠に未完成です。
スポンサーリンク