このプログラミング言語(連想配列)の比較では、 40種類以上のコンピュータプログラミング言語における連想配列データ構造または配列検索処理の機能を比較します。
以下は、さまざまなプログラミング言語における連想配列(「マッピング」、「ハッシュ」、「辞書」とも呼ばれる)の比較です。
AWKには、連想配列に対する言語レベルの組み込みサポートがあります。
例えば:
電話帳[ "Sally Smart" ] = "555-9999"電話帳[ "John Doe" ] = "555-1212"電話帳[ "J. Random Hacker" ] = "555-1337"以下のコードは、関連付けられた配列をループ処理し、その内容を出力します。
for ( name in phonebook ) { print name , " " , phonebook [ name ] }ユーザーは連想配列内の要素を検索したり、配列から要素を削除したりできます。
以下は、標準AWKにおいて、連結と組み込みの文字列区切り変数SUBSEPを使用して多次元連想配列をシミュレートする方法を示しています。
{ # 各入力行に対してmulti [ $ 1 SUBSEP $ 2 ] ++ ; } # END { for ( x in multi ) { split ( x , arr , SUBSEP ); print arr [ 1 ], arr [ 2 ], multi [ x ]; } }C言語には連想配列の標準的な実装はありませんが、BSDライセンスのサードパーティライブラリであるC Hash Tableが利用可能です。[ 1 ]
別のサードパーティライブラリであるuthashも、C構造体から連想配列を作成します。構造体は値を表し、構造体のフィールドの1つがキーとして機能します。[ 2 ]
最後に、GLibライブラリは連想配列をはじめとする多くの高度なデータ型をサポートしており、 GNUプロジェクトが推奨する実装です。[ 3 ]
GLibと同様に、AppleのクロスプラットフォームフレームワークであるCore Foundationは、いくつかの基本的なデータ型を提供しています。特に、参照カウント型のCFDictionaryとCFMutableDictionaryがあります。
C# は.NET Frameworkが提供するコレクション クラスを使用します。最も一般的に使用される連想配列型は でありSystem.Collections.Generic.Dictionary<TKey, TValue>、これは可変ハッシュ テーブルとして実装されています。.NET System.Collections.ImmutableFramework バージョン 4.5 以降および.NET Coreのすべてのバージョンで利用可能な比較的新しいパッケージには、 AVL ツリーSystem.Collections.Immutable.Dictionary<TKey, TValue>を使用して実装される 型も含まれています。通常、オブジェクトをその場で変更するメソッドは、代わりに変更後の元のオブジェクトの状態を表す新しいオブジェクトを返します。
以下に、可変辞書にデータを格納する3つの方法を示します。
Addメソッドは、キーと値を追加し、キーが既に辞書に存在する場合は例外をスローします。Dictionary < string , string > phoneBook = new (); phoneBook . Add ( "Sally Smart" , "555-9999" ); phoneBook [ "John Doe" ] = "555-1212" ; // C# では許可されていません。// phoneBook.Item("J. Random Hacker") = "553-1337"; phoneBook [ "J. Random Hacker" ] = "553-1337" ;辞書は、構築中に「コレクション初期化子」を使用して初期化することもできますAdd。これは、への繰り返し呼び出しにコンパイルされます。
Dictionary < string , string > phoneBook = new () { { "Sally Smart" , "555-9999" }, { "John Doe" , "555-1212" }, { "J. Random Hacker" , "553-1337" } };値は主にインデクサー(キーが存在しない場合は例外をスローします)とメソッドを使用して取得されます。このTryGetValueメソッドは、検索された値の出力パラメータと、キーが見つかったかどうかを示すブール値の戻り値を持ちます。
string sallyNumber = phoneBook [ "Sally Smart" ];string sallyNumber = ( phoneBook . TryGetValue ( "Sally Smart" , out string result ) ? result : "n/a" ;この例では、sallyNumber値には文字列が含まれます"555-9999"。
辞書は、キーのシーケンス、値のシーケンス、または型のインスタンスによって表されるキーと値のペアのシーケンスとして見ることができますが、順序は保証されません。ソートされた辞書の場合、プログラマは列挙時に を使用するか、LINQ拡張メソッドKeyValuePair<TKey, TValue>を使用することを選択できます。SortedDictionary<TKey, TValue>.Sort
以下は、foreachループを使用した列挙の例です。
// コレクションをループ処理して各エントリを表示します。foreach ( KeyValuePair < string , string > kvp in phoneBook ) { Console . WriteLine ( "電話番号 {0} は {1} です" , kvp . Key , kvp . Value ); }C++には、連想配列クラスが4つあります。std ::map(赤黒木TreeMap、他の言語の` map`に相当)とstd::unordered_map(ハッシュテーブル、他の言語の`map`に相当)です。残りの2つは`map`と`map`で、同じキーを持つ複数のエントリを許可します。HashMapstd::multimapstd::unordered_multimap
これらのクラスはテンプレート化されており、コレクションのインスタンスごとにキーと値のデータ型を異ならせることができます。mapクラスの特定のインスタンスでは、キーは同じ基本型でなければなりません。すべての値についても同様です。std::mapは通常、自己平衡二分探索木を使用して実装されますが、C++11 ではstd::unordered_mapハッシュテーブルのアルゴリズム特性を持つ と呼ばれる 2 番目のマップが定義されています。これは、標準テンプレートライブラリ(STL) の一般的なベンダー拡張機能でもあり、通常は と呼ばれhash_map、SGI や STLPort などの実装から利用できます。
import std ;using std :: string ; using std :: unordered_map ; int main ( int argc , char * argv [ ]) { unordered_map < string , string > phoneBook ; phoneBook.insert ( std :: make_pair ( "Sally Smart" , " 555-9999" )); phoneBook.insert ( std :: make_pair ( " John Doe" , "555-1212" )); phoneBook.insert ( std :: make_pair ( " J . Random Hacker" , "553-1337" ) ); }std::stringあるいは、これは一時的な値を生成するため、効率は劣ります。
import std ;using std :: string ; using std :: unordered_map ; int main ( int argc , char * argv []) { unordered_map < string , string > phoneBook ; phoneBook [ "Sally Smart" ] = "555-9999" ; phoneBook [ "John Doe" ] = "555-1212" ; phoneBook [ "J. Random Hacker" ] = "553-1337" ; }C++11で初期化リストが拡張されたことにより、以下に示すように、マップの構築中にエントリを追加できるようになりました。
import std ;using std :: string ; using std :: unordered_map ;int main () { unordered_map < string , string > phoneBook { { "Sally Smart" , "555-9999" }, { "John Doe" , "555-1212" }, { "J. Random Hacker" , "553-1337" } }; }以下のコード(C++03)でリストを反復処理できます。
// 'it' は std::unordered_map<std::string, std::string>::iterator 型です。for ( auto it = phoneBook . begin (); it != phoneBook . end (); ++ it ) { std :: println ( "{} = {}" , it -> first , it -> second ); }C++11 での同じタスク:
using std :: pair ; using std :: string ;for ( const pair < string , string >& it : phoneBook ) { std :: println ( "{} = {}" , it -> first , it -> second ); }C++17で利用可能な構造化バインディングを使用する:
for ( const auto & [ name , number ] : phoneBook ) { std :: println ( "{} = {}" , name , number ); }Cobraで空の辞書を初期化し、項目を追加する:
dic as Dictionary < of String , String > = Dictionary < of String , String > () dic . add ( 'Sally Smart' , '555-9999' ) dic . add ( 'John Doe' , '555-1212' ) dic . add ( 'J. Random Hacker' , '553-1337' )assert dic [ 'Sally Smart' ] == '555-9999'あるいは、辞書は構築時にすべての項目で初期化することもできます。
dic = { 'Sally Smart' : '555-9999' , 'John Doe' : '555-1212' , 'J. Random Hacker' : '553-1337' }辞書はforループで列挙できますが、順序は保証されません。
for key , val in dic print "[key]の電話番号は[val]です"ColdFusion Markup Language (CFML)における構造体は、連想配列に相当します。
dynamicKeyName = "John Doe" ; phoneBook = { "Sally Smart" = "555-9999" , " #dynamicKeyName# " = "555-4321" , "J. Random Hacker" = "555-1337" , UnknownComic = "???" }; writeOutput ( phoneBook.UnknownComic ); // ??? writeDump ( phoneBook ); // 構造体全体D言語はコア言語で連想配列を直接サポートしており、そのような配列はオープンアドレス指定のハッシュテーブルとして実装されています。[ 4 ]同等の例は次のようになります。
int main () { string [ string ] phone_book ; phone_book [ "Sally Smart" ] = "555-9999" ; phone_book [ "John Doe" ] = "555-1212" ; phone_book [ "J. Random Hacker" ] = "553-1337" ; return 0 ; }キーと値は任意の型にすることができますが、連想配列内のすべてのキーは同じ型でなければならず、依存する値についても同様です。
すべてのプロパティとそれに関連付けられた値をループ処理して出力するコードは、次のように記述できます。
foreach ( key , value ; phone_book ) { writefln ( "%s の番号: %s" , key , value ); }プロパティは次のように削除できます。
phone_book.remove ( " Sally Smart" ) ;Delphiは、TDictionary<T>を含むいくつかの標準コンテナをサポートしています。
SysUtils 、Generics.Collectionsを使用します。var PhoneBook : TDictionary < string , string >; Entry : TPair < string , string >;begin PhoneBook := TDictionary < string , string >. Create ; PhoneBook . Add ( 'Sally Smart' , '555-9999' ) ; PhoneBook . Add ( 'John Doe' , '555-1212' ) ; PhoneBook . Add ( 'J. Random Hacker' , '553-1337' ) ;for Entry in PhoneBook do Writeln ( Format ( 'Number for %s: %s' , [ Entry . Key , Entry . Value ])) ; end .2009年以前のDelphiバージョンでは、連想配列が直接サポートされていません。このような配列は、TStringsクラスを使用してシミュレートできます。
procedure TForm1 . Button1Click ( Sender : TObject ) ; var DataField : TStrings ; i : Integer ; begin DataField := TStringList . Create ;DataField.Values [ ' Sally Smart' ] := '555-9999' ; DataField.Values [ ' John Doe' ] := '555-1212' ; DataField.Values [ 'J . Random Hacker' ] : = ' 553-1337' ;// エントリにアクセスしてメッセージボックスに表示するShowMessage ( DataField . Values [ 'Sally Smart' ]) ;// 連想配列をループしますfor i := 0 to DataField . Count - 1 do begin ShowMessage ( 'Number for ' + DataField . Names [ i ] + ': ' + DataField . ValueFromIndex [ i ]) ; end ;DataField.Free ; end ;Erlangにはマッピングを表現するための多くの方法があり、標準ライブラリで最も一般的なものとしては、キーリスト、辞書、マップの3つが挙げられます。
キーリストはタプルのリストであり、各タプルの最初の要素はキー、2番目の要素は値です。キーリストを操作するための関数は、このlistsモジュールに用意されています。
電話帳= [{ "サリー・スミス" , "555-9999" }, { "ジョン・ドゥ" , "555-1212" }, { "J. ランダム・ハッカー" , "553-1337" }]。キーリストの要素にアクセスするには、次のlists:keyfind/3関数を使用します。
{_, Phone } = lists : keyfind ( "Sally Smith" , 1 , PhoneBook ), io : format ( "電話番号: ~s~n " , [ Phone ]).dict辞書は標準ライブラリのモジュールに実装されています。新しい辞書はdict:new/0関数を使用して作成され、新しいキーと値のペアは関数を使用して格納されますdict:store/3。
PhoneBook1 = dict : new (), PhoneBook2 = dict : store ( "Sally Smith" , "555-9999" , Dict1 ), PhoneBook3 = dict : store ( "John Doe" , "555-1212" , Dict2 ), PhoneBook = dict : store ( "J. Random Hacker" , "553-1337" , Dict3 ).このような逐次初期化は、Erlangでは適切な関数を用いてより慣用的に表現されるだろう。
PhoneBook = dict : from_list ([{ "Sally Smith" , "555-9999" }, { "John Doe" , "555-1212" }, { "J. Random Hacker" , "553-1337" }])辞書には以下のdict:find/2関数を使用してアクセスできます。
{ ok , Phone } = dict : find ( "Sally Smith" , PhoneBook ), io : format ( "Phone: ~s~n " , [ Phone ]).どちらの場合も、任意のErlang項をキーとして使用できます。バリエーションとしてはorddict、順序付き辞書を実装するモジュールや、gb_trees一般的な平衡木を実装するモジュールなどがあります。
マップはOTP 17.0で導入され[ 5 ]、キーリストと辞書の長所を組み合わせたものです。マップは次の構文で定義されます#{ K1 => V1, ... Kn => Vn }。
電話帳= #{ "Sally Smith" => "555-9999" , "John Doe" => "555-1212" , "J. Random Hacker" => "553-1337" }。このモジュールには、マップを操作するための基本的な関数が用意されていますmaps。例えば、このmaps:find/2関数はキーに関連付けられた値を返します。
{ ok , Phone } = maps : find ( "Sally Smith" , PhoneBook ), io : format ( "Phone: ~s~n " , [ Phone ]).辞書とは異なり、地図はパターンマッチングが可能です。
#{ "Sally Smith" , Phone } = PhoneBook , io : format ( "Phone: ~s~n " , [ Phone ]).Erlangは、既存のマップを基に新しいマップを作成する際に、値を変更したりキーを追加したりするなど、機能的な更新を行うための構文糖衣も提供しています。
PhoneBook2 = PhoneBook #{ % `:=` 演算子は、既存のキーに関連付けられた値を更新します"J. Random Hacker" : = "355-7331" ,% `=>`演算子は新しいキーと値のペアを追加し、既存のペアを置き換える可能性があります。"不思議の国のアリス" => "555-1865" }Map<'Key,'Value>実行時には、F# はCollections.Map<'Key,'Value>不変のAVL ツリーである型を提供します。
次の例では、コンストラクタを呼び出しますMap。コンストラクタは、タプルのリスト(角括弧で囲まれたセミコロンで区切られた要素のシーケンス)に対して操作を行います(F# では、タプルはカンマで区切られた要素のシーケンスです)。
let numbers = [ "Sally Smart" , "555-9999" ; "John Doe" , "555-1212" ; "J. Random Hacker" , "555-1337" ] |> MapMap値は、インデクサーやプロパティ(キーが存在しない場合は例外をItemスローします)などのメンバー、または関数を使用して検索できます。関数は、検索が成功した場合は、値が のオプション型を、失敗した場合は の値を返します。その後、パターンマッチングを使用して結果から生の値を抽出したり、デフォルト値を設定したりできます。TryFindSome<result>None
let sallyNumber = numbers .[ "Sally Smart" ] //またはlet sallyNumber = numbers.Item ( " Sally Smart" )let sallyNumber = match numbers.TryFind ( "Sally Smart" ) with | Some ( number ) -> number | None - > " n/a"上記の2つの例では、sallyNumber値には文字列が含まれます"555-9999"。
Dictionary<'TKey,'TValue>F# は .NET 言語であるため、.NET Frameworkの機能にもアクセスできます。これには、C# や Visual Basic で使用される主要な連想配列型である型(ハッシュテーブルとして実装されています) も含まれます。この型は、.NET Framework 上の他の言語と連携することを目的としたコードを作成する場合や、AVL ツリーよりもハッシュテーブルのパフォーマンス特性が優先される場合に推奨されます。System.Collections.Generic.Dictionary<'TKey,'TValue>
このdict関数は、変更を意図しない .NET ディクショナリを簡単に作成する手段を提供します。タプルのシーケンスを受け取り、 を実装する不変オブジェクトを返します。IDictionary<'TKey,'TValue>
let numbers = [ "Sally Smart" , "555-9999" ; "John Doe" , "555-1212" ; "J. Random Hacker" , "555-1337" ] |> dict可変辞書が必要な場合は、コンストラクタを直接呼び出すことができます。詳細については、このページのC#の例を参照してください。System.Collections.Generic.Dictionary<'TKey,'TValue>
let numbers = System.Collections.Generic.Dictionary < string , string > ( ) numbers.Add ( " Sally Smart" , " 555-9999" ) numbers . [ " John Doe" ] <- "555-1212" numbers.Item ( " J . Random Hacker" ) <- " 555-1337"IDictionaryインスタンスには、と同じように使用されるインデクサーがありますがMap、に相当するのは であり、TryFindこれTryGetValueは検索された値の出力パラメータと、キーが見つかったかどうかを示すブール値の戻り値を持っています。
let sallyNumber = let mutable result = "" if numbers . TryGetValue ( "Sally Smart" , & result ) then result else "n/a"F#では、出力パラメータがないかのように関数を呼び出し、通常の戻り値と出力パラメータに割り当てられた値を含むタプルを返すこともできます。
let sallyNumber = match numbers.TryGetValue ( " Sally Smart" ) with | true , number -> number | _ -> " n/a"辞書またはマップは、を使用して列挙できますSeq.map。
// コレクションをループして各エントリを表示します。numbers |> Seq . map ( fun kvp -> printfn "%O の電話番号は %O です" kvp . Key kvp . Value )Visual FoxProは、コレクションクラスを使用してマッピングを実装します。
mapping = NEWOBJECT ( "Collection" ) mapping .Add ( "Daffodils" , "flower2" ) && Add(object, key) – key は文字である必要がありますindex = mapping .GetKey ( "flower2" ) && インデックス値 1 を返しますobject = mapping( "flower2" ) && "Daffodils" を返します (キーで取得) object = mapping(1) && "Daffodils" を返します (インデックスで取得)GetKeyは、キーが見つからない場合は0を返します。
Go言語には、連想配列(「マップ」と呼ばれる)を言語レベルでサポートする機能が組み込まれています。マップのキーの型は、ブール型、数値型、文字列型、配列型、構造体型、ポインタ型、インターフェース型、チャネル型のいずれかに限られます。
マップ型が記述されます。map[keytype]valuetype
要素を一つずつ追加していく:
phone_book := make ( map [ string ] string ) // 空のマップを作成phone_book [ "Sally Smart" ] = "555-9999" phone_book [ "John Doe" ] = "555-1212" phone_book [ "J. Random Hacker" ] = "553-1337"マップリテラル:
phone_book := map [ string ] string { "Sally Smart" : "555-9999" , "John Doe" : "555-1212" , "J. Random Hacker" : "553-1337" , }マップを反復処理する:
// キーと値の両方に対してfor key , value := range phone_book { fmt . Printf ( "%s の番号: %s\n" , key , value ) }// キーのみを対象にfor key := range phone_book { fmt . Printf ( "名前: %s\n" , key ) }Haskellプログラミング言語は、ペアのリストという1種類の連想コンテナのみを提供します。
m = [( "Sally Smart" , "555-9999" ), ( "John Doe" , "555-1212" ), ( "J. Random Hacker" , "553-1337" )]main = print ( lookup "John Doe" m )出力:
「555-1212」とだけお伝えください。
検索関数は「Maybe」値を返します。見つからない場合は「Nothing」、見つかった場合は「Just 'result ' 」が返されます。
Haskellの実装として最も広く使われているグラスゴーHaskellコンパイラ(GHC)は、さらに2種類の連想コンテナを提供しています。他の実装でも同様の機能が提供される場合があります。
一つは多相関数マップ(不変平衡二分木として表現される)である。
import qualified Data.Map as M m = M . insert "Sally Smart" "555-9999" M . empty m' = M . insert "John Doe" "555-1212" m m'' = M . insert "J. Random Hacker" "553-1337" m'main = print ( M . lookup "John Doe" m'' :: Maybe String )出力:
「555-1212」とだけお伝えください。
整数キー専用のバージョンとして、Data.IntMap も存在します。
最後に、ポリモーフィックハッシュテーブルについて説明します。
import qualified Data.HashTable as Hmain = do m <- H . new ( == ) H . hashString H . insert m "Sally Smart" "555-9999" H . insert m "John Doe" "555-1212" H . insert m "J. Random Hacker" "553-1337" foo <- H . lookup m "John Doe" print foo出力:
「555-1212」とだけお伝えください。
ペアのリストと関数マップはどちらも純粋関数型のインターフェースを提供し、これはHaskellにおいてより慣用的な表現方法です。一方、ハッシュテーブルはIOモナドにおいて命令型のインターフェースを提供します。
Javaでは、連想配列はJavaコレクションフレームワークの一部である「マップ」として実装されています。J2SE 5.0以降、 Javaにジェネリクスが導入されたことで、コレクションに型を指定できるようになりました。たとえば、文字列を文字列にマッピングする連想配列は、次のように指定できます。
Map < String , String > phoneBook = new HashMap < String , String > (); phoneBook . put ( "Sally Smart" , "555-9999" ); phoneBook . put ( "John Doe" , "555-1212" ); phoneBook . put ( "J. Random Hacker" , "555-1337" );このgetメソッドはキーにアクセスするために使用されます。たとえば、式の値はphoneBook.get("Sally Smart")です"555-9999"。このコードは、HashMapクラスのコンストラクタを呼び出すことで、ハッシュマップを使用して連想配列を格納します。ただし、このコードはインターフェース に共通するメソッドのみを使用しているためMap、変数の定義やコードの残りの部分を変更したり、インターフェースを実装する他の基盤となるデータ構造を使用したりすることなく、TreeMapクラスのコンストラクタ(サブインターフェース を実装SortedMap)を呼び出すことで、自己平衡二分木を使用できます。phoneBookMap
Java のハッシュ関数は、HashMap や HashSet で使用されるメソッドによって提供されますObject.hashCode()。Java のすべてのクラスは を継承しているため、すべてObjectのオブジェクトはハッシュ関数を持っています。クラスはのデフォルトの実装をオーバーライドしてhashCode()、オブジェクトの特性により適したカスタムハッシュ関数を提供できます。
このObjectクラスにはequals(Object)、オブジェクトが別のオブジェクトと等しいかどうかをテストするメソッドも含まれています。Java のハッシュデータ構造は、オブジェクトがメソッド間で次の契約を維持することに依存していhashCode()ますequals()。
2つのオブジェクトaとbについて、
a.equals ( b ) == b.equals ( a )もしa.equals ( b )ならば、a.hashCode ( ) == b.hashCode ( )この契約を維持するために、をオーバーライドするクラスはequals()もオーバーライドする必要がありhashCode()、その逆も同様です。つまり、はとhashCode()同じプロパティ(またはプロパティのサブセット)に基づいていますequals()。
ハッシュデータ構造とオブジェクトとの間のもう一つの契約は、オブジェクトがマップに挿入されると、hashCode()およびメソッドの結果が変更されないということです。このため、ハッシュ関数はオブジェクトの不変equals()プロパティに基づいて作成するのが一般的に良い方法です。
同様に、TreeMapやその他のソート済みデータ構造では、データ型に順序が定義されている必要があります。データ型がComparableインターフェースを実装することで既に独自の順序を定義しているか、マップ構築時にカスタム順序Comparatorを指定する必要があります。上記のHashMapと同様に、TreeMapのキーの相対的な順序は、マップに挿入された後は変更されるべきではありません。
JavaScript(およびその標準化版であるECMAScript)は、プロトタイプベースのオブジェクト指向言語です。
Map最新のJavaScriptでは、`map`クラスと`map`クラスを使用して連想配列を扱いますWeakMap。`map`にはデフォルトではキーは含まれておらず、明示的に追加されたもののみが含まれます。キーと値は、関数、オブジェクト、任意のプリミティブ型など、任意の型にすることができます。
マップは構築時にすべてのアイテムで初期化できます。
const phoneBook = new Map ([ [ "Sally Smart" , "555-9999" ], [ "John Doe" , "555-1212" ], [ "J. Random Hacker" , "553-1337" ], ]);あるいは、空のマップを初期化してからアイテムを追加することもできます。
const phoneBook = new Map (); phoneBook.set ( " Sally Smart" , "555-9999" ); phoneBook.set ( " John Doe" , "555-1212" ); phoneBook.set ( " J . Random Hacker" , "553-1337" );マップの要素にアクセスするには、次のget方法を使用できます。
const sallyNumber = phoneBook.get ( " Sally Smart" ) ;この例では、値にsallyNumberは「555-9999」という文字列が含まれます。
マップ内のキーは順序付けられています。そのため、マップオブジェクトを反復処理すると、挿入された順序でキーが返されます。以下は、forループを使用した列挙の例です。
// コレクションをループ処理して各エントリを表示します。for ( const [ name , number ] of phoneBook ) { console . log ( `電話番号${ name }は${ number }です` ); }キーは次のように取り外すことができます。
phoneBook.delete ( " Sally Smart" ) ;オブジェクトはマップに似ています。どちらもキーに値を設定したり、値を取得したり、キーを削除したり、キーに値が格納されているかどうかを検出したりできます。こうした理由(そして他に組み込みの代替手段がなかったため)から、オブジェクトは歴史的にマップとして使用されてきました。
しかし、重要な違いがあり、場合によってはマップの方が好ましいこともあります。JavaScriptでは、オブジェクトはプロパティ名から値へのマッピング、つまり連想配列ですが、1つの注意点があります。オブジェクトのキーは文字列またはシンボルでなければなりません(ネイティブオブジェクトや暗黙的に文字列キーに変換されるプリミティブも使用できます)。オブジェクトには、連想配列とは関係のないもう1つの機能があります。オブジェクトにはプロトタイプがあり、ユーザー定義のキーと競合する可能性のあるデフォルトキーが含まれています。そのため、オブジェクトがプロパティを定義していない場合、プロパティのルックアップを実行すると、プロトタイプの定義を参照することになります。
オブジェクトリテラルは のように記述します{ property1: value1, property2: value2, ... }。例:
const myObject = { "Sally Smart" : "555-9999" , "John Doe" : "555-1212" , "J. Random Hacker" : "553-1337" , };プロトタイプのプロパティがルックアップに使用されないようにするには、Object.setPrototypeOf次の関数を使用できます。
Object.setPrototypeOf ( myObject , null ) ;ECMAScript 5 (ES5) 以降では、プロトタイプは以下のようにしてバイパスすることもできますObject.create(null)。
const myObject = Object.create ( null ) ;Object.assign ( myObject , { " Sally Smart" : "555-9999" , "John Doe" : "555-1212" , "J. Random Hacker" : "553-1337" , }) ;プロパティ名が有効な識別子である場合、引用符は省略できます。例:
const myOtherObject = { foo : 42 , bar : false };ルックアップは、プロパティアクセス表記法を使用して記述されます。角括弧表記法は常に機能しますが、ドット表記法は識別子キーに対してのみ機能します。
myObject [ "John Doe" ] myOtherObject . foo列挙可能なプロパティとそれに関連付けられた値を、以下のようにループ処理することもできます(for-inループ)。
for ( const property in myObject ) { const value = myObject [ property ]; console . log ( `myObject[ ${ property } ] = ${ value } ` ); }または(for-ofループ):
for ( const [ property , value ] of Object . entries ( myObject )) { console . log ( ` ${ property } = ${ value } ` ); }プロパティは次のように削除できます。
myObject [ "Sally Smart" ]を削除します。前述のとおり、プロパティは文字列とシンボルです。すべてのネイティブオブジェクトとプリミティブは暗黙的に文字列に変換できるため、次のようにできます。
myObject [ 1 ] // キーは "1"。myObject[1] == myObject["1"] であることに注意してください。myObject [[ "a" , "b" ]] // キーは "a,b" myObject [{ toString () { return "hello world" ; } }] // キーは "hello world"現代のJavaScriptでは、連想配列としてArray型を使用するのは好ましくないと考えられています。一般的には、この目的にはObject型とMap/WeakMapクラスが最適とされています。その理由は、Array型をプロトタイプで拡張し、Object型をそのまま維持すれば、連想配列に対してforループやfor-inループが期待通りに動作するからです。この問題は、JavaScriptの組み込み型を拡張するためにプロトタイプを多用し、時には無差別に使用するJavaScriptフレームワークの普及によって、より顕著になりました。
この問題に関する詳細は、「JavaScript配列とオブジェクトのプロトタイプに関する啓発デー」を参照してください。
Juliaでは、以下の操作で連想配列を操作します。
辞書を宣言します:
電話帳= Dict ( "Sally Smart" => "555-9999" , "John Doe" => "555-1212" , "J. Random Hacker" => "555-1337" )アクセス要素:
電話帳[ 「サリー・スマート」]要素を追加する:
電話帳[ "新しい連絡先" ] = "555-2222"要素を削除:
削除! (電話帳、「サリー・スマート」)キーと値をイテラブルとして取得する:
キー(電話帳)値(電話帳)KornShell 93 およびそれに準拠するシェル (ksh93、bash4 など)では、連想配列に対して以下の操作を使用できます。
意味:
typeset -A phonebook ; # ksh93; bash4+ では、「typeset」はより推奨される「declare」の同義語であり、この場合、phonebook =([ "Sally Smart" ]= "555-9999" [ "John Doe" ]= "555-1212" [ "[[J. Random Hacker]]" ]= "555-1337" ) ;逆参照:
${ phonebook [ "John Doe" ] } ;Lispは元々「リスト処理」言語として構想され、その最も重要なデータ型の1つは連結リストであり、これは連想リスト(「alist」)として扱うことができます。
' (( "サリー・スマート " . "555-9999 " ) ( "ジョン・ドゥ " . "555-1212 " ) ( "J. ランダム・ハッカー " . "553-1337 " ))この構文は、キーと値のペア(x . y)を示すために使用されます。alist 内のキーと値は、同じ型である必要はありません。Lisp とScheme は、連想配列と同様の方法で alist を操作するための演算子を提供します。consassoc
Common Lispには、連想リストの扱いに特化した一連の操作が存在し、それらはすべて非破壊的に動作します。
エントリを追加するにはacons、関数を使用して新しい連想リストを作成し、返します。Common Lisp の連想リストはスタックを模倣しており、後入れ先出し (LIFO) の原則に従うため、リストの先頭に要素が追加されます。
( let (( phone-book NIL )) ( setf phone-book ( acons "Sally Smart" "555-9999" phone-book )) ( setf phone-book ( acons "John Doe" "555-1212" phone-book )) ( setf phone-book ( acons "J. Random Hacker" "555-1337" phone-book )))この機能は、操作のための便宜と解釈できるcons。[ 6 ]
;; ;; (cons (cons KEY VALUE) ALIST) ;;の効果は、;; (acons KEY VALUE ALIST) ( let (( phone-book ' (( "Sally Smart" . "555-9999" ) ( "John Doe" . "555-1212" )))) ( cons ( cons "J. Random Hacker" "555-1337" ) phone-book )) と同等です。もちろん、破壊的なpush操作では、関連付けリストにエントリを挿入することもできます。ただし、マッピングの有効性を維持するためには、エントリはキーと値のペアで構成されている必要があります。
( push ( cons "Dummy" "123-4567" )電話帳)キーによるエントリの検索は、 を介して実行されますassoc。 は、テスト述語と方向、特に連想リストを末尾から先頭に向かって検索するように設定できます。結果が正の場合、値だけでなくエントリ cons 全体が返されます。一致するキーが見つからない場合は、値が返されますNIL。
( assoc "John Doe" phone-book :test #' string= )には 2 つの一般化がassoc存在します。assoc-ifは、各エントリのキーをテストする述語関数を期待し、NIL呼び出し時に述語が 以外の値を生成する最初のエントリを返します。assoc-if-notはロジックを反転させ、同じ引数を受け取りますが、 を生成する最初のエントリを返しますNIL。
;; キーが「John Doe」と等しい最初のエントリを検索します。( assoc-if #' ( lambda ( key ) ( string= key "John Doe" )) phone-book );; キーが「Sally Smart」でも「John Doe」でもない最初のエントリを検索します( assoc-if-not #' ( lambda ( key ) ( member key ' ( "Sally Smart" "John Doe" ) :test #' string= )) phone-book )逆のプロセス、つまり値によるエントリの検出は、 を利用しますrassoc。
;; 値が「555-9999」の最初のエントリを検索します。;; エントリの文字列値を「string="」述語でテストします。( rassoc "555-9999" phone-book :test #' string= )対応する一般化rassoc-ifがrassoc-if-not存在する。
;; 値が「555-9999」である最初のエントリを検索します。( rassoc-if #' ( lambda ( value ) ( string= value "555-9999" )) phone-book );; 値が「555-9999」ではない最初のエントリを検索します。( rassoc-if-not #' ( lambda ( value ) ( string= value "555-9999" )) phone-book )findこれまでのエントリ検索関数はすべて、 、find-if、などの一般的なリスト中心のバリアント、find-if-notおよび やpositionその派生関数などの関連関数に置き換えることができます。
;; キーが「John Doe」で値が「555-1212」のエントリを検索します。( find ( cons "John Doe" "555-1212" ) phone-book :test #' equal )削除は、特定の対応物を持たないため、破壊的なものも含め、リスト機能に基づいて行われます。
;; キーが「John Doe」に等しいエントリを含まない alist を作成して返します。( remove-if #' ( lambda ( entry ) ( string= ( car entry ) "John Doe" )) phone-book )反復処理は、リストを引数として受け取る関数を用いることで実現できます。
;; 「map」を使用して反復処理します。( map NIL #' ( lambda ( entry ) ( destructuring-bind ( key . value ) entry ( format T "~&~s => ~s" key value ))) phone-book );; "dolist" を使用して反復処理します。( dolist ( entry phone-book ) ( destructuring-bind ( key . value ) entry ( format T "~&~s => ~s" key value )))これらは構造化されたリストであるため、処理および変換操作を制約なく適用できる。
;; 「電話帳」の値のベクトルを返します。( map 'vector #' cdr phone-book );; 「map-into」を使用して「phone-book」を破壊的に変更します。( map-into phone-book #' ( lambda ( entry ) ( destructuring-bind ( key . value ) entry ( cons ( reverse key ) ( reverse value )))) phone-book )連想リストは線形的な性質を持つため、比較的小規模なデータセットに使用されます。Common Lisp はハッシュテーブルデータ型もサポートしており、SchemeではSRFI 69で実装されています。ハッシュテーブルは連想リストよりもオーバーヘッドが大きいものの、要素数が多い場合にははるかに高速なアクセスを提供します。また、連想リストとは異なり、Common Lisp のハッシュテーブルはエントリの挿入順序を保持しないという特徴があります。
Common Lisp のハッシュテーブルは、関数を使用して構築されます。make-hash-tableこの関数の引数には、エントリキーをテストするための述語など、さまざまな設定が含まれます。任意のオブジェクト、さらには単一のハッシュテーブルインスタンス内の異質性も許容しますが、このキー関数の仕様は区別可能なエンティティに限定されます。Common Lisp 標準では、、、、:testのサポートのみが義務付けられていますが、具体的な実装では追加またはカスタムの操作が許可されています。eqeqlequalequalp
( let (( phone-book ( make-hash-table :test #' equal ))) ( setf ( gethash "Sally Smart" phone-book ) "555-9999" ) ( setf ( gethash "John Doe" phone-book ) "555-1212" ) ( setf ( gethash "J. Random Hacker" phone-book ) "553-1337" ))このgethash関数を使用すると、キーに関連付けられた値を取得できます。
( gethash "John Doe"電話帳)さらに、キーが存在しない場合のデフォルト値を指定することもできます。
( gethash "Incognito"電話帳'no-such-key )の呼び出しはgethash実際には 2 つの値を返します。1 つはキーの値または代替値、もう 1 つはブール型のインジケータで、Tハッシュテーブルにキーが含まれている場合は を返し、NIL含まれていない場合は を返します。
(複数値バインド(値にキーが含まれている) ( gethash "Sally Smart" phone-book ) ( if contains-key ( format T "~&関連付けられた値は: ~s" valueです) ( format T "~&キーが見つかりませんでした。" )))remhashキーに関連付けられたエントリを削除する場合に使用します。
( remhash "J. Random Hacker"電話帳)clrhashハッシュテーブルを完全に空にします。
( clrhash電話帳)この専用maphash関数は、ハッシュテーブルの反復処理に特化しています。
( maphash #' ( lambda ( key value ) ( format T "~&~s => ~s" key value )) phone-book )あるいは、このloop構造は、キー、値、またはその両方の組み合わせによって、反復処理を可能にする仕組みを備えている。
;; ハッシュテーブルのキーと値を反復処理します。(電話帳のハッシュキーをキーとしてループし、(ハッシュ値値)を使用して(フォーマットT "~&~s => ~s"キー値)を実行します);; ハッシュテーブルの値を反復処理します。(電話帳のハッシュ値である値に対してループし、その値を出力します)さらに別のオプションではwith-hash-table-iterator、イテレータを作成するマクロを呼び出します。このマクロの処理は呼び出し元によって制御されることを想定しています。
(ハッシュテーブルイテレータ付き(エントリジェネレータ電話帳) (ループ実行(複数値バインド(エントリキー値を持つ) (エントリジェネレータ) (エントリを持つ場合(フォーマットT "~&~s => ~s"キー値) (ループ終了)))))Lispでは、構造体やオブジェクト指向プログラミングの機能と、リスト、配列、ハッシュテーブルを組み合わせることで、複合的な抽象データ型を容易に構築できます。
LPCは、ドライバに応じて「map」または「mapping」と呼ばれる基本型として連想配列を実装します。キーと値は任意の型にすることができます。マッピングリテラルは と記述します。手続き型コードは次のようになります。([ key_1 : value_1, key_2 : value_2 ])
マッピングphone_book = ([]); phone_book [ "Sally Smart" ] = "555-9999" ; phone_book [ "John Doe" ] = "555-1212" ; phone_book [ "J. Random Hacker" ] = "555-1337" ;マッピングは、上記のように、書き込みの場合と同様に、インデックス演算子を使用して読み取りにもアクセスされます。したがって、phone_book["Sally Smart"] は文字列 "555-9999" を返し、phone_book["John Smith"] は 0 を返します。存在のテストは、関数 member() を使用して行われます。例:if(member(phone_book, "John Smith")) write("John Smith is listed.\n");
削除は、ドライバに応じてm_delete()またはmap_delete()と呼ばれる関数を使用して実行されます。m_delete(phone_book, "Sally Smart");
AmylaarファミリーのLPCドライバは、二次的な数値インデックスを使用して多値マッピングを実装します(MudOSファミリーの他のドライバは多値マッピングをサポートしていません)。構文例:
マッピングphone_book = ([ : 2 ]); phone_book [ "Sally Smart" , 0 ] = "555-9999" ; phone_book [ "Sally Smart" , 1 ] = "99 Sharp Way" ; phone_book [ "John Doe" , 0 ] = "555-1212" ; phone_book [ "John Doe" , 1 ] = "3 Nigma Drive" ; phone_book [ "J. Random Hacker" , 0 ] = "555-1337" ; phone_book [ "J. Random Hacker" , 1 ] = "77 Massachusetts Avenue" ;foreach() 構文をサポートするほど最新の LPC ドライバは、それを使用してマッピング型を反復処理します。
Luaでは、「table」は基本型であり、配列(数値インデックス、高速)としても連想配列としても使用できます。
キーと値は、nil以外の任意の型を指定できます。以下では、非数値インデックスに焦点を当てます。
テーブルリテラルは のように記述します{ value, key = value, [index] = value, ["non id string"] = value }。例:
phone_book = { [ "Sally Smart" ] = "555-9999" , [ "John Doe" ] = "555-1212" , [ "J. Random Hacker" ] = "553-1337" , -- 末尾のカンマはOK }aTable = { -- テーブルを値として使用subTable = { 5 , 7.5 , k = true }, -- キーは "subTable" -- 関数を値として使用[ 'John Doe' ] = function ( age ) if age < 18 then return "Young" else return "Old!" end end , -- テーブルと関数 (およびその他の型) もキーとして使用できます}キーが有効な識別子(予約語ではない)である場合、引用符は省略できます。識別子は大文字と小文字を区別します。
ルックアップは、常に機能する角括弧表記、または識別子キーにのみ有効なドット表記のいずれかを使用して記述します。
print ( aTable [ " John Doe " ] ( 45 ) ) x = aTable.subTable.kイテレータまたはforループを使用して、すべてのキーと関連付けられた値をループ処理することもできます。
simple = { [ true ] = 1 , [ false ] = 0 , [ 3.14 ] = math.pi , x = 'x' , [ "!" ] = 42 } function FormatElement ( key , value ) return "[" .. tostring ( key ) .. "] = " .. value .. "," end -- すべてのキーを反復処理しますtable . foreach ( simple , function ( k , v ) io.write ( FormatElement ( k , v )) end ) print "" for k , v in pairs ( simple ) do io.write ( FormatElement ( k , v )) end print "" k = nil repeat k , v = next ( simple , k ) if k ~= nil then io.write ( FormatElement ( k , v )) end until k == nil print ""エントリを削除するには、その値をnilに設定します。
シンプル。x = nil同様に、値を上書きしたり、追加したりすることもできます。
simple [ '%' ] = "パーセント" simple [ '!' ] = 111MathematicaとWolfram Languageは連想配列を表すために連想式を使用します。[ 7 ]
電話帳= <| "Sally Smart" -> "555-9999" , "John Doe" -> "555-1212" , "J. Random Hacker" -> "553-1337" |> ;アクセスするには:[ 8 ]
電話帳[[キー[ "サリー・スマート" ]]]キーが文字列の場合は、Key キーワードは不要なので、次のようになります。
電話帳[[ "サリー・スマート" ]]キー[電話帳] 値[電話帳]
MUMPSでは、すべての配列は連想配列です。言語レベルで組み込まれた連想配列の直接サポートは、メモリに格納されるプロセス固有のプライベート配列(「ローカル」と呼ばれる)だけでなく、ディスクに格納され、複数のジョブで同時に使用できる永続的な共有グローバル配列にも適用されます。グローバル変数の名前には、ローカル変数と区別するために、サーカムフレックス「^」が前に付きます。
SET ^phonebook("Sally Smart")="555-9999" ;; 永続的なデータを保存 SET phonebook("John Doe")="555-1212" ;; 一時データの保存 SET phonebook("J. Random Hacker")="553-1337" ;; 一時データの保存 MERGE ^phonebook=phonebook ;; 一時データを永続データにコピーする要素の値にアクセスするには、添え字付きの名前を使用するだけで済みます。
「電話番号:」と書き込む、^phonebook("サリー・スマート")、!関連付けられた配列をループ処理するには、次のようにします。
SET NAME="" FOR S NAME=$ORDER(^phonebook(NAME)) QUIT:NAME="" WRITE NAME," 電話番号:",^phonebook(NAME),!
Objective-Cで記述されたCocoaとGNUstep は、 (可変バージョンの) クラス clusterを使用して連想配列を処理します。このクラスは、任意の 2 つのオブジェクト間の代入を可能にします。キー オブジェクトのコピーは、に挿入される前に作成されるため、キーはプロトコルに準拠する必要があります。辞書に挿入されるとき、値オブジェクトは参照カウントを増やすために保持メッセージを受け取ります。値オブジェクトは、辞書から削除されるとき (明示的に削除されるか、同じキーを持つ別のオブジェクトが辞書に追加されるかのいずれか) に、解放メッセージを受け取ります。NSMutableDictionaryNSDictionaryNSMutableDictionaryNSCopying
NSMutableDictionary * aDictionary = [[ NSMutableDictionary alloc ] init ]; [ aDictionary setObject : @"555-9999" forKey : @"Sally Smart" ]; [ aDictionary setObject : @"555-1212" forKey : @"John Doe" ]; [ aDictionary setObject : @"553-1337" forKey : @"Random Hacker" ];割り当てられたオブジェクトにアクセスするには、このコマンドを使用できます。
id anObject = [ aDictionary objectForKey : @"Sally Smart" ];すべてのキーまたは値は、以下を使用して列挙できますNSEnumerator。
NSEnumerator * keyEnumerator = [ aDictionary keyEnumerator ]; id key ; while (( key = [ keyEnumerator nextObject ])) { // ... ここで処理します ... }Mac OS X 10.5以降およびiPhone OSでは、辞書キーを次の構造を使用してより簡潔に列挙できますNSFastEnumeration。[ 11 ]
for ( id key in aDictionary ) { // ... ここで処理します ... }さらに実用的なことに、構造化データグラフはCocoa、特にNSDictionary(NSMutableDictionary)を使用して簡単に作成できます。これは、次の簡潔な例で示すことができます。
NSDictionary * aDictionary = [ NSDictionary dictionaryWithObjectsAndKeys : [ NSDictionary dictionaryWithObjectsAndKeys : @"555-9999" , @"Sally Smart" , @"555-1212" , @"John Doe" , nil ], @"students" , [ NSDictionary dictionaryWithObjectsAndKeys : @"553-1337" , @"Random Hacker" , nil ], @"hackers" , nil ];関連するフィールドには、キーパスを使用してすばやくアクセスできます。
id anObject = [ aDictionary valueForKeyPath : @"students.Sally Smart" ];OCamlプログラミング言語は、 3種類の連想コンテナを提供します。最も単純なのは、ペアのリストです。
# let m = [ "Sally Smart" , "555-9999" ; "John Doe" , "555-1212" ; "J. Random Hacker" , "553-1337" ];; val m : ( string * string ) list = [ ( "Sally Smart" , "555-9999" ); ( "John Doe" , "555-1212" ); ( "J. Random Hacker" , "553-1337" ) ] # List . assoc "John Doe" m ;; - : string = "555-1212"2つ目は、ポリモーフィックハッシュテーブルです。
# let m = Hashtbl.create3 ;; val m : ( ' _a , ' _b ) Hashtbl.t = <abstr> # Hashtbl.add m " Sally Smart" "555-9999" ; Hashtbl.add m " John Doe " " 555-1212" ; Hashtbl.add m " J. Random Hacker " " 553-1337 " ;; - : unit = ( ) # Hashtbl.find m " John Doe " ;; - : string = " 555-1212 "上記のコードはHashtbl.hash、OCaml のデフォルトのハッシュ関数を使用しています。これは、すべての型に対して自動的に定義されます。ハッシュ関数を変更するには、ファンクタインターフェースを使用してHashtbl.Makeモジュールを作成します。たとえば、 を使用しますMap。
最後に、関数マップ(不変平衡二分木として表現される):
# module StringMap = Map . Make ( String );; ... # let m = StringMap . add "Sally Smart" "555-9999" StringMap . empty let m = StringMap . add "John Doe" "555-1212" m let m = StringMap . add "J. Random Hacker" "553-1337" m ;; val m : string StringMap . t = < abstr > # StringMap . find "John Doe" m ;; - : string = "555-1212"を使用するにはMap、キー型と比較関数を定義するモジュールをファンクタに提供する必要があることに注意してくださいMap.Make。サードパーティライブラリ ExtLib は、関数マップのポリモーフィックバージョンである [ 12 ] を提供しており、PMap作成時に比較関数が与えられます。
ペアのリストと関数マップはどちらも純粋な関数型インターフェースを提供する。対照的に、ハッシュテーブルは命令型インターフェースを提供する。多くの操作において、ハッシュテーブルはペアのリストや関数マップよりも大幅に高速である。
OptimJプログラミング言語はJava 5の拡張機能です。Javaと同様に、OptimJはマップを提供しますが、真の連想配列も提供します。Javaの配列は負でない整数でインデックス付けされますが、連想配列は任意の型のキーでインデックス付けされます。
String [ String ] phoneBook = { "Sally Smart" -> "555-9999" , "John Doe" -> "555-1212" , "J. Random Hacker" -> "553-1337" };// String[String] は Java 型ではなく、optimj 型です。// 文字列によってインデックス付けされた文字列の連想配列です。// 値を反復処理するfor ( String number : phoneBook ) { System . out . println ( number ); }// 前のステートメントの出力: "555-9999" "555-1212" "553-1337"// キーを反復処理するfor ( String name : phoneBook . keys ) { System . out . println ( name + " -> " + phoneBook [ name ] ); } // phoneBook[name] はキーで値にアクセスします (Java の配列アクセスに似ています) // 例: phoneBook["John Doe"] は "555-1212" を返しますもちろん、多次元配列を定義したり、Java配列と連想配列を組み合わせたり、マップと連想配列を組み合わせたりすることも可能です。
int [ String ][][ double ] a ; java . util . Map < String [ Object ] , Integer > b ;Perl 5 には、連想配列を言語レベルでサポートする機能が組み込まれています。現代の Perl では、連想配列をハッシュと呼びます。連想配列という用語は古いドキュメントにも見られますが、やや古風な表現とみなされています。Perl 5 のハッシュはフラットです。キーは文字列、値はスカラーです。ただし、値は配列や他のハッシュへの参照にすることができ、標準の Perl 5 モジュールである Tie::RefHash を使用すると、ハッシュを参照キーとともに使用できます。
ハッシュ変数は、スカラー、配列、その他のデータ型と区別するために、%記号でマークされます。ハッシュリテラルはキーと値のリストであり、Perlのトークンを使用する形式が推奨されます。このトークンは意味的にはカンマとほぼ同じで、キーと値の関連付けをより明確にします。=>
my %phone_book = ( 'Sally Smart' => '555-9999' , 'John Doe' => '555-1212' , 'J. Random Hacker' => '553-1337' , );ハッシュ要素にアクセスするには、構文を使用します$hash_name{$key}。キーは中括弧で囲まれ、ハッシュ名には がプレフィックスとして付きます$。これは、ハッシュ要素自体がハッシュの一部であってもスカラー値であることを示しています。 の値は$phone_book{'John Doe'}です'555-1212'。%は、 を要求する場合など、ハッシュ全体を参照する場合にのみ使用されますkeys %phone_book。
キーと値のリストは、それぞれ組み込み関数とを使用して抽出できますkeys。valuesたとえば、ハッシュのすべてのキーを出力するには、次のようにします。
foreach $name ( keys %phone_book ) { print $name , "\n" ; }関数を使用すると、(キー、値)のペアを反復処理できますeach。
while (( $name , $number ) = each %phone_book ) { print '電話番号 ' , $name , ': ' , $number , "\n" ; }ハッシュ「参照」とは、ハッシュを指すスカラー値であり、中括弧を区切り文字として使用したリテラル形式で指定します。構文はハッシュリテラルを指定する場合とほぼ同じです。
my $phone_book = { 'Sally Smart' => '555-9999' , 'John Doe' => '555-1212' , 'J. Random Hacker' => '553-1337' , };ハッシュ参照内の値にアクセスするには、逆参照演算子を使用します。
print $phone_book -> { 'Sally Smart' };ハッシュ参照に含まれるハッシュ全体を、keys関数のように参照する必要がある場合、構文は次のようになります。
foreach $name ( keys % { $phone_book }) { print '電話番号 ' , $name , ': ' , $phone_book -> { $name }, "\n" ; }Perl 6(現在は「Raku」と改名)には、連想配列(ハッシュ、または「連想」の役割を果たすオブジェクトと呼ばれる)を言語レベルでサポートする組み込み機能があります。Perl 5と同様に、Perl 6のデフォルトのハッシュはフラットです。キーは文字列、値はスカラーです。すべてのキーを自動的に文字列に変換しないようにハッシュを定義することもできます。このようなハッシュは、キーが文字列化されたものではなく元のオブジェクトのままであるため、「オブジェクトハッシュ」と呼ばれます。
ハッシュ変数は通常、スカラー、配列、その他のデータ型と視覚的に区別し、反復処理に対する動作を定義するために、%記号でマークされます。ハッシュリテラルはキーと値のリストであり、キーと値の関連付けをより明確にするために、Perlのトークンを使用する形式が推奨されます。=>
私の%phone-book = 'Sally Smart' => '555-9999' , 'John Doe' => '555-1212' , 'J. Random Hacker' => '553-1337' , ; ハッシュ要素にアクセスするには、次の構文を使用します%hash_name{$key}。キーは中括弧とハッシュ名で囲まれます(Perl 5 とは異なり、シジルは変更されません)。 の値は%phone-book{'John Doe'}です'555-1212'。
キーと値のリストは、それぞれ組み込み関数とを使用して抽出できますkeys。valuesたとえば、ハッシュのすべてのキーを出力するには、次のようにします。
for %phone-book . keys -> $name { say $name ; } デフォルトでは、ハッシュを反復処理すると、キーと値のペアが得られます。
for %phone-book -> $entry { say "$entry.key() の番号: $entry.value()" ; # 拡張補間機能を使用 } 以下の方法を用いることで、キー値と値の値を交互に取得することも可能ですkv。
for %phone-book . kv -> $name , $number { say "$name の電話番号: $number" ; } Rakuには参照がありません。ハッシュはフラット化されない単一のパラメータとして渡すことができます。サブルーチンがハッシュのみを受け入れるようにするには、シグネチャに%記号を使用します。
sub list-phone-book ( %pb ) { for %pb . kv -> $name , $number { say "$name の電話番号: $number" ; } } 電話帳一覧( %phone-book ); 段階的型付けの原則に従い、ハッシュには型制約が適用され、有効なキーのセットが特定の型に限定される場合があります。
# キーが整数値(「Int」型)のみであるハッシュを定義します。my %numbersWithNames { Int }; # キーは、この例のように整数である必要があります。%numbersWithNames . push ( 1 => "one" ); # 文字列をキーとして使用するとエラーが発生します。%numbersWithNames . push ( "key" => "two" ); PHPの組み込み配列型は、実際には連想配列です。数値インデックスを使用する場合でも、PHP は内部的に配列を連想配列として格納します。[ 13 ]そのため、PHP は連続していない数値インデックスの配列を持つことができます。キーは整数型 (浮動小数点数は整数に切り捨てられます) または文字列型である必要がありますが、値は他の配列やオブジェクトを含む任意の型にすることができます。配列は異種混合です。つまり、1 つの配列に異なる型のキーを持つことができます。PHP の連想配列は、PHP に組み込まれていないツリー、リスト、スタック、キュー、その他の一般的なデータ構造を表すために使用できます。
連想配列は、以下の構文を使用して宣言できます。
$phonebook = array (); $phonebook [ 'Sally Smart' ] = '555-9999' ; $phonebook [ 'John Doe' ] = '555-1212' ; $phonebook [ 'J. Random Hacker' ] = '555-1337' ;// または$phonebook = array ( 'Sally Smart' => '555-9999' , 'John Doe' => '555-1212' , 'J. Random Hacker' => '555-1337' , );// または、PHP 5.4 以降では$phonebook = [ 'Sally Smart' => '555-9999' , 'John Doe' => '555-1212' , 'J. Random Hacker' => '555-1337' , ];// または$phonebook [ 'contacts' ][ 'Sally Smart' ][ 'number' ] = '555-9999' ; $phonebook [ 'contacts' ][ 'John Doe' ][ 'number' ] = '555-1212' ; $phonebook [ 'contacts' ][ 'J. Random Hacker' ][ 'number' ] = '555-1337' ;PHPでは、連想配列を次のようにループ処理できます。
foreach ( $phonebook as $name => $number ) { echo '電話番号 ' , $name , ': ' , $number , " \n " ; }// 最後の配列の例では、次のように使用します。foreach ( $phonebook [ 'contacts' ] as $name => $num ) { echo '名前: ' , $name , ', 電話番号: ' , $num [ 'number' ], " \n " ; }PHPには配列を操作するための豊富な関数セットがあります。[ 14 ]
SplObjectStorage文字列や整数の代わりにオブジェクトをキーとして使用できる連想配列は、標準PHPライブラリ(SPL)のクラスを使用して実装できます。 [ 15 ]
Pikeには連想配列(マッピングと呼ばれる)のサポートが組み込まれています。マッピングは次のように作成されます。
マッピング(文字列:文字列) phonebook = ([ "Sally Smart" : "555-9999" , "John Doe" : "555-1212" , "J. Random Hacker" : "555-1337" ]);マッピングへのアクセスと存在確認は、インデックス演算子を使用して行います。したがってphonebook["Sally Smart"]、は文字列を返し"555-9999"、phonebook["John Smith"]は0を返します。
マッピングを反復処理するには、次の方法を使用できますforeach。
foreach ( phonebook ; string key ; string value ) { write ( "%s:%s \n " , key , value ); }または、イテレータオブジェクトを使用する方法:
マッピング。イテレータi = get_iterator ( phonebook ); while ( i- > index ()) { write ( "%s:%s \n " , i- > index (), i- > value ()); i- > next (); }マッピングの要素はm_delete、削除されたインデックスの値を返す を使用して削除できます。
string sallys_number = m_delete ( phonebook , "Sally Smart" );PostScriptでは、連想配列は辞書と呼ばれます。レベル1のPostScriptでは明示的に作成する必要がありましたが、レベル2では二重山括弧構文を使用した直接宣言が導入されました。
% レベル 1 宣言3 dict dup begin /red (rouge) def /green (vert) def /blue (bleu) def end% レベル 2 宣言<< /red (rot) /green (gruen) /blue (blau) >>どちらの方法も、辞書をオペランドスタック上に残します。辞書には、 を直接使用してアクセスすることgetも、 を使用して辞書を辞書スタックに配置することで暗黙的にアクセスすることもできますbegin。
% 前の 2 つの辞書がまだオペランド スタックにある状態で/red get print % 'rot' を出力しますbegin green print % 'vert' を出力しますendforall辞書の内容は、特定の順序ではなく、を使用して反復処理できます。
% レベル 2 の例<< /This 1 /That 2 /Other 3 >> { exch =print ( is ) print == } forall出力例:
これは2 、これは1 、その他は3です。辞書は、 を使って拡張(レベル 1 では定義されたサイズまでのみ)または変更できput、 を使ってエントリを削除できますundef。
% 再利用しやすいように辞書を定義します: /MyDict << /rouge (赤) /vert (緑) >> def% 追加MyDict /bleu (青) put% 変更MyDict /vert (green) put% 何かを削除するMyDict /rouge undefPythonでは、連想配列は「辞書」と呼ばれます。辞書リテラルは中括弧で囲まれます。
from typing import Any電話帳: dict [ str , str ] = { "Sally Smart" : "555-9999" , "John Doe" : "555-1212" , "J. Random Hacker" : "553-1337" , }辞書項目には、配列インデックス演算子を使用してアクセスできます。
print ( phonebook [ "Sally Smart" ]) # '555-9999' と出力されます辞書のすべてのキーをループ処理する:
for key in phonebook : print ( key , phonebook [ key ])# 印刷物: # サリー・スマート 555-9999 # J. ランダム・ハッカー 553-1337 # ジョン・ドゥ 555-1212(キー、値)タプルを反復処理する:
for key , value in phonebook.items ( ) : print ( key , value )# 印刷物: # サリー・スマート 555-9999 # J. ランダム・ハッカー 553-1337 # ジョン・ドゥ 555-1212辞書のキーは、ステートメントを使用して個別に削除できますdel。キーと値のペアが削除される前に、対応する値を取得するには、`dict` 型の `pop` メソッドを使用します。
del phonebook [ "John Doe" ] val = phonebook . pop ( "Sally Smart" ) print ( phonebook . keys ()) # キーは1つだけ残っています# ['J. Random Hacker'] と出力されますPython 2.7 および 3.x では、辞書内包表記(リスト内包表記に類似) もサポートされています。これは、任意のイテレータから辞書を生成するための簡潔な構文です。
square_dict : dict [ int , int ] = { i : i * i for i in range ( 5 )} print ( square_dict ) # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16} と出力されますprint ({ key : value for key , value in phonebook . items () if "J" in key }) # {'J. Random Hacker': '553-1337', 'John Doe': '555-1212'} と出力されます厳密に言えば、辞書は連想配列の上位集合です。なぜなら、キーも値も単一のデータ型に限定されないからです。Pythonの用語で言えば、辞書は「連想リスト」と考えることができます。例えば、以下のコードも有効です。
電話帳: dict [ Any , Any ] = { "Sally Smart" : "555-9999" , "John Doe" : None , "J. Random Hacker" : -3.32 , 14 : " 555-3322" , }辞書のキーは、変更不可能なデータ型でなければなりません。Pythonでは、文字列はその実装方法により変更不可能です。
Redでは、組み込みのmap![ 17 ]データ型が、単語、文字列、スカラーキー型の値を任意の型の値にマッピングする連想配列を提供します。内部的にはハッシュテーブルがルックアップに使用されます。
マップは、のようにリテラルとして記述することも#(key1 value1 key2 value2 ...)、を使用して作成することもできますmake map! [key1 value1 key2 value2 ...]。
赤[タイトル: 「私の地図」]my-map:マップを作成![ "Sally Smart" "555-9999" "John Doe" "555-1212" "J. Random Hacker" "553-1337" ]Red はキーと値の両方で大文字小文字を保持しますが、デフォルトではルックアップは大文字小文字を区別しません。<code>select</code> と <code>put</code> の <code>/case</code> 絞り込みを使用して大文字小文字の区別を強制することができます。もちろん、<code>word!</code> 値をキーとして使用することも可能です。その場合、マップを作成する際には一般的に <code>set-word!</code> 値を使用することが推奨されますが、検索や作成には任意の単語タイプを使用できます。my-other-map:マップを作成! [ foo: 42 bar: false ]; ブロックは縮小も評価もされないため、上記の例ではキー <code>bar</code> は <code>logic!</code> の値 false ではなく <code>word!</code> <code>false</code> に関連付けられています。後者が必要な場合は、リテラル構文を使用できます。my-other-map:マップを作成! [ foo: 42 bar: # [ false ]]または、作成後にキーを追加することもできます。my-other-map:マップを作成! [ foo: 42 ] my-other-map /bar: false; ルックアップは、<code>path!</code>表記法または<code>select</code>アクションを使用して記述できます。my-map "Sally Smart" my-othermap /fooを選択します; また、<code>foreach</code>を使用してすべてのキーと値をループ処理することもできます。foreach [ key value ] my-map [ print [ key "is associated to " value ] ]キーは <code>remove/key</code> を使用して削除できます。/key my-map "Sally Smart"を削除REXXでは、連想配列は「幹変数」または「複合変数」と呼ばれます。
KEY = 'Sally Smart' PHONEBOOK . KEY = '555-9999' KEY = 'John Doe' PHONEBOOK . KEY = '555-1212' KEY = 'J. Random Hacker' PHONEBOOK . KEY = '553-1337'数値キーを持つ幹変数は通常1から始まり、そこから増加します。慣例として、キーが0の幹変数には幹に含まれる項目の総数が格納されます。
名前. 1 = 'サリー・スマート' 名前. 2 = 'ジョン・ドゥ' 名前. 3 = 'J.ランダムハッカー' 名前. 0 = 3REXXには、ステム変数のキーに自動的にアクセスする簡単な方法がありません。通常、キーは数値キーを持つ別の連想配列に格納されます。
Rubyでは、ハッシュテーブルは次のように使用されます。
電話帳= { 'Sally Smart' => '555-9999' , 'John Doe' => '555-1212' , 'J. Random Hacker' => '553-1337' }電話帳[ 'John Doe' ]Rubyは、以下の構文でハッシュループとイテレーションをサポートしています。
irb(main):007:0> ### キーと値を反復処理しますirb(main):008:0* phonebook . each { | key , value | puts key + " => " + value } Sally Smart => 555-9999 John Doe => 555-1212 J. Random Hacker => 553-1337 => {"Sally Smart"=>"555-9999", "John Doe"=>"555-1212", "J. Random Hacker"=>"553-1337"} irb(main):009:0> ### キーのみを反復処理しますirb(main):010:0* phonebook . each_key { | key | puts key } Sally Smart John Doe J. Random Hacker => {"Sally Smart"=>"555-9999", "John Doe"=>"555-1212", "J. Random Hacker"=>"553-1337"} irb(main):011:0> ### 値のみを反復処理irb(main):012:0* phonebook . each_value { | value | puts value } 555-9999 555-1212 553-1337 => {"Sally Smart"=>"555-9999", "John Doe"=>"555-1212", "J. Random Hacker"=>"553-1337"}Rubyは、ハッシュのマージ、特定の条件を満たす要素の選択または拒否、反転(キーと値の入れ替え)、ハッシュを配列に平坦化するなど、ハッシュに対するその他多くの便利な操作もサポートしています。
Rustの標準ライブラリには、ハッシュマップ ( std::collections::HashMap) とB ツリーマップ ( std::collections::BTreeMap) が用意されています。これらは同じ名前のメソッドをいくつか共有していますが、挿入できるキーの型に関する要件が異なります。 は、HashMapキーがEq(等価関係) とHash( ハッシュ可能性 ) 特性を実装している必要があり、エントリは指定されていない順序で格納されます。一方、は、キーに(全体順序BTreeMap) 特性が必要で、エントリはキーの型によって定義された順序で格納されます。この順序は、デフォルトのイテレータによって反映されます。Ord
use std :: collections :: HashMap ;let mut phone_book : HashMap < String , String > = HashMap :: new (); phone_book . insert ( "Sally Smart" , "555-9999" ); phone_book . insert ( "John Doe" , "555-1212" ); phone_book . insert ( "J. Random Hacker" , "555-1337" );// または、次のようにもできます。let phone_book : HashMap < String , String > = hash_map ! { "Sally Smart" => "555-9999" , "John Doe" => "555-1212" , "J. Random Hacker" => "555-1337" , };デフォルトのイテレータは、すべてのエントリをタプルとして走査します。HashMapイテレータは、エントリを無指定の順序で走査し、BTreeMapイテレータは、キーの型によって定義された順序でエントリを走査します。
for ( name , number ) in & phone_book { println! ( "{} = {}" , name , number ); }キー用のイテレータもあります。
for name in phone_book.keys ( ) { println! ( "{}" , name ) ; }S言語には連想配列型があります。
電話帳 = Assoc_Type[]; 電話帳["サリー・スマート"] = "555-9999" 電話帳["John Doe"] = "555-1212" 電話帳["J. Random Hacker"] = "555-1337" 関連付けられた配列をループ処理する方法はいくつかあります。
foreach name (phonebook) { vmessage ("%s %s", name, phonebook[name]); } ソートされたリストを出力するには、S言語の標準配列に対する強力なサポートを活用するのが良いでしょう。
keys = assoc_get_keys(phonebook); i = array_sort(keys); vals = assoc_get_values(phonebook); array_map (Void_Type, &vmessage, "%s %s", keys[i], vals[i]); ScalaはMapフレームワークの一部として不変クラスを提供していますscala.collection。
val phonebook = Map ( "Sally Smart" -> "555-9999" , "John Doe" -> "555-1212" , "J. Random Hacker" -> "553-1337" )Scalaの型推論では、これは であると判断されますMap[String, String]。配列にアクセスするには:
電話帳から「サリー・スマート」を取得します。これは型を返します。これはScalaにおけるHaskellのMaybeモナドOptionに相当します。
Smalltalkでは、次のものDictionaryが使用されます。
電話帳:= Dictionary new .電話帳: 'Sally Smart'に'555-9999'を追加.電話帳: 'John Doe'に'555-1212'を追加.電話帳: 'J. Random Hacker'に'553-1337'を追加.エントリにアクセスするには、メッセージを#at:辞書オブジェクトに送信します。
電話帳:サリー・スマートこれにより、次のようになります。
「555-9999」 ディクショナリは、等価性に基づいてハッシュ化または比較を行い、キーと値の両方を 強い参照としてマークします。同一性に基づいてハッシュ化/比較を行うバリアント(IdentityDictionary)や、弱い参照を保持するバリアント(WeakKeyDictionary / WeakValueDictionary)も存在します。すべてのオブジェクトが#hashを実装しているため、どのオブジェクトでもキーとして使用できます(もちろん値としても使用できます)。
SNOBOLは、連想配列を採用した最初のプログラミング言語の一つ(あるいは最初の言語)です。SNOBOLでは、連想配列はテーブルと呼ばれます。
PHONEBOOK = TABLE () PHONEBOOK [ 'Sally Smart' ] = '555-9999' PHONEBOOK [ 'John Doe' ] = '555-1212' PHONEBOOK [ 'J. Random Hacker' ] = '553-1337'Standard MLプログラミング言語のSML'97規格では、連想コンテナは提供されていません。しかし、Standard MLの様々な実装では、連想コンテナが提供されています。
人気の高いStandard ML of New Jersey (SML/NJ) 実装のライブラリには、順序付き関数 (不変) 連想配列の共通インターフェースORD_MAPを定義するシグネチャ (「インターフェース」のようなもの) が提供されています。キーの型とコンパレータを記述するユーザー提供の構造を使用して、対応する型の順序付きマップ (型はそれぞれ、自己平衡二分探索木、ソート済み連想リスト、赤黒木、およびスプレッド木) を作成できる汎用ファンクタ(、、、および)がいくつかあります。ファンクタは、インターフェースに従って構造を返します。さらに、整数キーを使用する連想配列用の事前定義モジュールが 2 つあります。BinaryMapFnListMapFnRedBlackMapFnSplayMapFnORD_MAPIntBinaryMapIntListMap
- structure StringMap = BinaryMapFn ( struct type ord_key = string val compare = String . compare end ); structure StringMap : ORD_MAP- val m = StringMap . insert ( StringMap . empty , "Sally Smart" , "555-9999" ) val m = StringMap . insert ( m , "John Doe" , "555-1212" ) val m = StringMap . insert ( m , "J. Random Hacker" , "553-1337" ); val m = T { cnt = 3 , key = "John Doe" , left = T { cnt = 1 , key = "J. Random Hacker" , left = E , right = E , value = "553-1337" }, right = T { cnt = 1 , key = "Sally Smart" , left = E , right = E , value = "555-9999" }, value = "555-1212" } : string StringMap . map - StringMap.find ( m , " John Doe" ) ; val it = SOME "555-1212" : string optionSML/NJは、ポリモーフィックハッシュテーブルも提供します。
-例外NotFound ;例外NotFound - val m : ( string , string ) HashTable . hash_table = HashTable . mkTable ( HashString . hashString , op =) ( 3 , NotFound ); val m = HT { eq_pred = fn , hash_fn = fn , n_items = ref 0 , not_found = NotFound ( - ), table = ref [ |NIL , NIL , NIL , NIL , NIL , NIL , NIL , NIL , NIL , NIL , NIL , NIL ,... | ]} : ( string , string ) HashTable . hash_table - HashTable . insert m ( "Sally Smart" , "555-9999" ); val it = () : unit - HashTable . insert m ( "John Doe" , "555-1212" ); val it = () : unit - HashTable . insert m ( "J. Random Hacker" , "553-1337" ); val it = () : unit HashTable . find m "John Doe" ; (* 見つからない場合は NONE を返します *) val it = SOME "555-1212" : string option - HashTable . lookup m "John Doe" ; (* 見つからない場合は例外を発生させます *) val it = "555-1212" : stringファンクタを使用することで、単相ハッシュテーブルもサポートされますHashTableFn。
別のStandard ML実装であるMoscow MLも、いくつかの連想コンテナを提供しています。まず、構造体内に多相ハッシュテーブルを提供します。また、上記のSML/NJライブラリのいくつかの関数マップは、構造体、構造体、構造体Polyhashとして利用可能です。BinarymapSplaymapIntmap
Tclには、連想配列のセマンティクスをサポートする機能が2つあります。「配列」は変数の集合です。「辞書」は連想配列の完全な実装です。
set { phonebook ( Sally Smart )} 555 - 9999 set john { John Doe } set phonebook ( $john ) 555 - 1212 set { phonebook ( J. Random Hacker )} 553 - 1337変数名にスペース文字が含まれている場合は、変数名を中括弧(置換は行われない)または二重引用符(置換が行われる)で囲む必要があります。
あるいは、複数の配列要素を単一のコマンドで設定することもできます。その場合は、マッピングをリストとして指定します(空白を含む単語は中括弧で囲みます)。
配列set phonebook [ list { Sally Smart } 555 - 9999 { John Doe } 555 - 1212 { J. Random Hacker } 553 - 1337 ]配列のエントリを1つアクセスして標準出力に出力するには:
puts $phonebook ( Sally \ Smart )これにより、以下の結果が返されます。
555-9999 配列全体を辞書として取得するには:
配列から電話帳 を取得結果は次のようになります(キーの順序は指定されていません。これは辞書が順序付けされていないからではなく、配列が順序付けされているためです)。
{サリー・スマート} 555-9999 { J.ランダムハッカー} 553-1337 {ジョン・ドゥ} 555-1212set phonebook [ dict create { Sally Smart } 555 - 9999 { John Doe } 555 - 1212 { J. Random Hacker } 553 - 1337 ]アイテムを検索するには:
dict get $phonebook { John Doe }辞書を反復処理するには:
foreach { name number } $phonebook { puts "名前: $name\n電話番号: $number" }Visual Basic は、 Microsoft Scripting Runtime (Visual Basic 6 に同梱)の Dictionary クラスを使用できます。ただし、すべてのバージョンに共通する標準的な実装はありません。
' プロジェクトのプロパティで SCRRUN.DLL への参照が必要ですDim phoneBook As New Dictionary phoneBook . Add "Sally Smart" , "555-9999" phoneBook . Item ( "John Doe" ) = "555-1212" phoneBook ( "J. Random Hacker" ) = "553-1337" For Each name In phoneBook MsgBox name & " = " & phoneBook ( name ) NextVisual Basic .NET は、.NET Frameworkが提供するコレクション クラスを使用します。
以下のコードは、辞書の作成とデータ入力の方法を示しています(詳細については、このページのC#の例を参照してください)。
Dim dic As New System.Collections.Generic.Dictionary ( Of String , String ) dic.Add ( " Sally Smart" , " 555-9999" ) dic ( " John Doe " ) = "555-1212" ) dic.Item ( " J . Random Hacker" ) = " 553-1337")別の構文としては、コレクション初期化子を使用する方法があり、これは個々の呼び出しにコンパイルされますAdd。
Dim dic As New System.Collections.Dictionary ( Of String , String ) From { { " Sally Smart" , "555-9999" } , { "John Doe" , "555-1212" }, { "J. Random Hacker" , " 553-1337" } }アクセス方法を示す例(C# アクセスを参照):
Dim sallyNumber = dic ( "Sally Smart" ) ' またはDim sallyNumber = dic . Item ( "Sally Smart" )Dim result As String = Nothing Dim sallyNumber = If ( dic . TryGetValue ( "Sally Smart" , result ), result , "n/a" )列挙の例(#C# 列挙を参照):
' コレクションをループして各エントリを表示します。For Each kvp As KeyValuePair ( Of String , String ) In dic Console . WriteLine ( "電話番号 {0} は {1} です" , kvp . Key , kvp . Value ) Next他の多くのコマンドラインインタープリタとは異なり、Windows PowerShellには連想配列を定義するための言語レベルの組み込みサポートがあります。
$phonebook = @{ 'Sally Smart' = '555-9999' ; 'John Doe' = '555-1212' ; 'J. Random Hacker' = '553-1337' }JavaScriptと同様に、プロパティ名が有効な識別子である場合は、引用符を省略できます。
$myOtherObject = @{ foo = 42 ; bar = $false }エントリはセミコロンまたは改行で区切ることができます。
$myOtherObject = @{ foo = 42 bar = $false ;ザズ= 3 }キーと値は、任意の.NETオブジェクト型にすることができます。
$now = [DateTime] :: Now $tomorrow = $now . AddDays ( 1 ) $ProcessDeletionSchedule = @{ ( Get-Process notepad ) = $now ( Get-Process calc ) = $tomorrow }空の連想配列を作成し、後から単一のエントリ、あるいは他の連想配列を追加することも可能です。
$phonebook = @{} $phonebook += @{ 'Sally Smart' = '555-9999' } $phonebook += @{ 'John Doe' = '555-1212' ; 'J. Random Hacker' = '553-1337' }配列インデックス演算子、プロパティ演算子、またはAdd()基となる.NETオブジェクトのメソッドを使用して、新しいエントリを追加することもできます。
$phonebook = @{} $phonebook [ 'Sally Smart' ] = '555-9999' $phonebook . 'John Doe' = '555-1212' $phonebook . Add ( 'J. Random Hacker' , '553-1337' )割り当てられたオブジェクトを逆参照するには、配列インデックス演算子、プロパティ演算子、またはItem().NETオブジェクトのパラメーター化されたプロパティを使用できます。
$phonebook [ 'Sally Smart' ] $phonebook . 'John Doe' $phonebook . Item ( 'J. Random Hacker' )連想配列をループ処理するには、次のようにします。
$phonebook.Keys | foreach { " Number for {0}: {1}" -f $ _ , $phonebook . $_ }エントリは、Remove()基となる.NETオブジェクトのメソッドを使用して削除できます。
$phonebook.Remove ( ' Sally Smart' )ハッシュテーブルを追加できます。
$hash1 = @{ a = 1 ; b = 2 } $hash2 = @{ c = 3 ; d = 4 } $hash3 = $hash1 + $hash2多くのデータシリアル化フォーマットは連想配列もサポートしています(この表を参照)。
JSONでは、連想配列はオブジェクトとも呼ばれます。キーは文字列のみになります。
{ "サリー・スマート" : "555-9999" , "ジョン・ドゥ" : "555-1212" , "J.ランダムハッカー" : "555-1337" }TOMLはハッシュマップに直接マッピングするように設計されています。TOMLでは連想配列をテーブルと呼びます。TOML内のテーブルは、「展開」方式またはインライン方式のいずれかで表現できます。キーは文字列のみを使用できます。
[電話帳] 「サリー・スマート」=「555-9999」「ジョン・ドゥ」=「555-1212」「J.ランダムハッカー」=「555-1337」電話帳= { "サリー・スマート" = "555-9999" , "ジョン・ドゥ" = "555-1212" , "J.ランダムハッカー" = "555-1337" }YAMLの連想配列は、マップ要素またはキーと値のペアとも呼ばれます。YAMLではキーの型に制限はなく、特にスカラー値や文字列値に限定されません。
サリー・スマート:555-9999 ジョン・ドゥ:555-1212 J・ランダム・ハッカー:555-1337hcreate()、hdestroy()およびhsearch()