Comparison of programming languages (associative array): Difference between revisions

Content deleted Content added
m F#: {{code}}
 
(136 intermediate revisions by 33 users not shown)
Line 2:
{{TOC limit|3}}
 
This '''Comparisoncomparison of programming languages (associative arrays)''' compares the features of [[associative array]] [[data structure]]s or array-lookup processing for over 39 various40 computer [[programming language]]s.
 
==Language support==
Line 8:
The following is a comparison of [[associative array]]s (also "mapping", "hash", and "dictionary") in various programming languages.
 
=== [[Awk]] AWK===
Awk[[AWK]] has built-in, language-level support for associative arrays.
 
For example:
 
<sourcesyntaxhighlight lang="awk">
phonebook["Sally Smart"] = "555-9999"
phonebook["John Doe"] = "555-1212"
phonebook["J. Random Hacker"] = "555-1337"
</syntaxhighlight>
</source>
 
YouThe canfollowing alsocode looploops through an associated array asand followsprints its contents:
 
<sourcesyntaxhighlight lang=awk>
for (name in phonebook) {
print name, " ", phonebook[name]
}
</syntaxhighlight>
</source>
 
YouThe user can alsosearch checkfor if an element iselements in thean associative array, and delete elements from an associativethe array.
 
MultiThe following shows how multi-dimensional associative arrays can be simulated in standard AwkAWK using concatenation and e.g.the built-in string-separator variable SUBSEP:
 
<sourcesyntaxhighlight lang=awk>
{ # for every input line
multi[$1 SUBSEP $2]++;
Line 42:
}
}
</syntaxhighlight>
</source>
 
===C===
=== [[C (programming language)|C]] ===
There is no standard implementation of an associative arrayarrays in [[C (programming language)|C]], but a 3rd -party library, C Hash Table, with BSD license, is available .<ref>[https://web.archive.org/web/20071015024120/http://www.cl.cam.ac.uk/~cwc22/hashtable/ here], archived [https://web.archive.org/web/20040902160534/http://www.cl.cam.ac.uk/~cwc22/hashtable/ here], with the source code available [https://github.com/davidar/c-hashtable/ here]. [[POSIX]] 1003.1-2001 describes the functions <code>hcreate()</code>, <code>hdestroy()</code> and <code>hsearch()</code>.</ref>
 
Another 3rd -party library, [http://uthash.sourceforge.net/ uthash], also creates associative arrays from C structures. A structure represents a value, and one of the structure fields actsserves as the key.<ref>{{cite web |title=uthash: a hash table for C structures |url=https://uthash.sourceforge.net/ |website=Github |access-date=3 August 2020}}</ref>
 
Finally, the [[GLib]] library also supports associative arrays, along with many other advanced data types and is the recommended implementation of the GNU Project.[<ref>{{cite web |title=Hash Tables |url=https://developer.gnome.org/glib/stable/glib-Hash-Tables.html] |website=Gnome Developer |access-date=3 August 2020}}</ref>
 
Similar to [[GLib]], [[Apple Inc.|Apple]]'s cross-platform [[Core Foundation]] framework provides several basic data types. In particular, there are reference -counted CFDictionary and CFMutableDictionary.
 
===C#===
=== [[C Sharp (programming language)|C#]] ===
<!-- Note: Be aware when editing that this section and its subsections are linked to by the F# and Visual Basic .NET sections -->
[[C Sharp (programming language)|C#'s]] uses the collection classes provided by the [[.NET Framework]]. The most commonly used associative array type is <code>System.Collections.Generic.Dictionary<TKey, TValue></code>, which is implemented as a mutable hash table. The relatively new <code>System.Collections.Immutable</code> package, available in .NET Framework versions 4.5 and above in, and in all versions of [[.NET Core]], also includes the <code>System.Collections.Immutable.Dictionary<TKey, TValue></code> type, which is implemented using an [[AVL tree]]. The methods that would normally mutate the object in-place instead return a new object that represents the state of the original object after mutation.
 
====Creation====
 
The following demonstrates three means of populating a mutable dictionary:
* the <code>Add</code> method, which adds a key and value and throws an [[exception handling|exception]] if the key already exists in the dictionary,;
* assigning to the indexer, which overwrites any existing value, if present,; and
* assigning to the backing property of the indexer, for which the indexer is [[syntactic sugar]] (not applicable to C#, see [[#F#|F#]] or [[#Visual Basic .NET|VB.NET]] examples) assigning to the backing property of the indexer, which is what the indexer is syntax sugar for.
 
<source lang=CSharp>
<syntaxhighlight lang="csharp">
Dictionary<string, string> dic = new Dictionary<string, string>();
var dictionary = new Dictionary<string, string>();
dic.Add("Sally Smart", "555-9999");
dic[dictionary.Add("JohnSally DoeSmart"] =, "555-12129999");
dictionary["John Doe"] = "555-1212";
// Not allowed in C#.
// dicdictionary.Item("J. Random Hacker") = "553-1337";
dicdictionary["J. Random Hacker"] = "553-1337";
</syntaxhighlight>
</source>
 
The dictionary can also be initialized during construction using a "collection initializer", which compiles to repeated calls to <code>Add</code>.
 
<syntaxhighlight lang="csharp">
The dictionary can also be initialized with all entries during construction using a ''collection initializer'', which compiles down to repeated calls to <code>Add</code>.
var dictionary = new Dictionary<string, string> {
<source lang=CSharp>
var dic = new Dictionary<string, string> {
{ "Sally Smart", "555-9999" },
{ "John Doe", "555-1212" },
{ "J. Random Hacker", "553-1337" }
};
</syntaxhighlight>
</source>
 
===={{anchor|C# access}}Access by key====
Values are primarily retrieved using the indexer (which throws an exception if the key does not exist) and the <code>TryGetValue</code> method, which has an output parameter for the sought value and a Boolean return-value indicating whether the key was found.
 
<syntaxhighlight lang="csharp">
Values are primarily retrieved using the indexer (which throws an exception if the key does not exist) and the <code>TryGetValue</code> method, which has an output parameter for the sought value and a Boolean return value indicating whether the key was found.
var sallyNumber = dictionary["Sally Smart"];
<source lang=CSharp>
</syntaxhighlight>
var sallyNumber = dic["Sally Smart"];
<syntaxhighlight lang="csharp">
</source>
var sallyNumber = (dictionary.TryGetValue("Sally Smart", out var result) ? result : "n/a";
<source lang=CSharp>
</syntaxhighlight>
var sallyNumber = (dic.TryGetValue("Sally Smart", out var result) ? result : "n/a";
</source>
In this example, the <code>sallyNumber</code> value will now contain the string <code>"555-9999"</code>.
 
===={{anchor|C# enumeration}}Enumeration====
A dictionary can be viewed as a sequence of keys, sequence of values, or sequence of pairs of keys and values represented by instances of the <code>KeyValuePair<TKey, TValue></code> type, although there is no guarantee of order. For a sorted dictionary, the programmer could choose to use a <code>SortedDictionary<TKey, TValue></code> or use the <code>.Sort</code> [[Language Integrated Query|LINQ]] extension method when enumerating.
 
A dictionary can be viewed as a sequence of keys, sequence of values, or sequence of pairs of keys and values represented by instances of the <code>KeyValuePair<TKey, TValue></code> type, though there is no guarantee of order. For a sorted dictionary, the programmer could choose to use a <code>SortedDictionary<TKey, TValue></code> or use the <code>.Sort</code> [[Language Integrated Query|LINQ]] extension method when enumerating.
 
The following demonstrates enumeration using a [[foreach loop]]:
<sourcesyntaxhighlight lang=CSharp"csharp">
// loop through the collection and display each entry.
foreach (KeyValuePair<string,string> kvp in dicdictionary)
{
Console.WriteLine("Phone number for {0} is {1}", kvp.Key, kvp.Value);
}
</syntaxhighlight>
</source>
 
=== [[C++]] ===
[[C++ also]] has a form of associative array called [[map (C++)|<code>std::map</code>]] (see [[Standard Template Library#Containers]]). One could create a phone-book map with the samefollowing informationcode as above usingin C++ with the following code:
 
<sourcesyntaxhighlight lang=Cpp"cpp">
#include <map>
#include <string>
Line 119:
phone_book.insert(std::make_pair("J. Random Hacker", "553-1337"));
}
</syntaxhighlight>
</source>
 
Or less efficiently, as itthis creates temporary <code>std::string</code> values:
<sourcesyntaxhighlight lang=Cpp"cpp">
#include <map>
#include <string>
Line 132:
phone_book["J. Random Hacker"] = "553-1337";
}
</syntaxhighlight>
</source>
 
With the extension of [[C++11#Initializer lists|initialization lists]] in C++11, entries can be added during a map's construction as shown below:
 
<sourcesyntaxhighlight lang=Cpp"cpp">
#include <map>
#include <string>
Line 147:
};
}
</syntaxhighlight>
</source>
 
You can iterate through the list with the following code (C++03):
 
<sourcesyntaxhighlight lang=Cpp"cpp">
std::map<std::string, std::string>::iterator curr, end;
for(curr = phone_book.begin(), end = phone_book.end(); curr != end; ++curr)
std::cout << curr->first << " = " << curr->second << std::endl;
</syntaxhighlight>
</source>
 
The same task in new C++11:
 
<sourcesyntaxhighlight lang=Cpp"cpp">
for(const auto& curr : phone_book)
std::cout << curr.first << " = " << curr.second << std::endl;
</syntaxhighlight>
</source>
 
Using the structured binding available in [[C++17]]:
 
<sourcesyntaxhighlight lang=Cpp"cpp">
for (const auto& [name, number] : phone_book) {
std::cout << name << " = " << number << std::endl;
}
</syntaxhighlight>
</source>
 
In C++, the <code>std::map</code> class is [[Generic programming#Templates in C.2B.2B|templated]] which allows the [[data type]]s of keys and values to be different for different <code>map</code> instances. For a given instance of the <code>map</code> class the keys must be of the same base type. The same must be true for all of the values. Although <code>std::map</code> is typically implemented using a [[self-balancing binary search tree]], C++11 defines a second map called <code>[[std::unordered_map]]</code>, which withhas the algorithmic characteristics of a hash table. This is a common vendor extension to the [[Standard Template Library]] (STL) as well, usually called <code>hash_map</code>, being available from such implementations as SGI and STLPort.
 
=== [[CFML]] Cobra===
Initializing an empty dictionary and adding items in [[Cobra (programming language)|Cobra]]:
A structure in CFML is equivalent to an associative array:
{{sxhl|2=python|1=<nowiki/>
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'
}}
Alternatively, a dictionary can be initialized with all items during construction:
{{sxhl|2=python|1=<nowiki/>
dic = {
'Sally Smart':'555-9999',
'John Doe':'555-1212',
'J. Random Hacker':'553-1337'
}
}}
The dictionary can be enumerated by a for-loop, but there is no guaranteed order:
{{sxhl|2=python|1=<nowiki/>
for key, val in dic
print "[key]'s phone number is [val]"
}}
 
===ColdFusion Markup Language===
<source lang=CFS>
A structure in [[ColdFusion Markup Language]] (CFML) is equivalent to an associative array:
 
<syntaxhighlight lang=CFS>
dynamicKeyName = "John Doe";
phoneBook = {
Line 187 ⟶ 211:
writeOutput(phoneBook.UnknownComic); // ???
writeDump(phoneBook); // entire struct
</syntaxhighlight>
</source>
 
=== [[Cobra (programming language)|Cobra]] ===
Initializing an empty dictionary and adding items:
 
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'
 
Alternatively, a dictionary can be initialized with all items during construction:
 
dic = {
'Sally Smart':'555-9999',
'John Doe':'555-1212',
'J. Random Hacker':'553-1337'
}
 
The dictionary can be enumerated by a for-loop, but there is no guaranteed order:
 
for key, val in dic
print "[key]'s phone number is [val]"
 
===D===
=== [[D programming language|D]] ===
[[D programming language|D]] offers direct support for associative arrays in the core language; such arrays are implemented as a chaining hash table with binary trees.<ref>{{Cite web|title=Associative Arrays - D Programming Language|url=https://dlang.org/spec/hash-map.html|access-date=2021-05-07|website=dlang.org}}</ref> The equivalent example would be:
D offers direct support for associative arrays
in the core language – they are implemented as a chaining hash table with binary trees.<ref>{{Cite web|url=http://digitalmars.com/d/2.0/hash-map.html |title=Associative Arrays |accessdate=2011-02-01 |work= |date= }}</ref> The equivalent example would be:
 
<sourcesyntaxhighlight lang=D"d">
int main() {
string[ string ] phone_book;
Line 224:
return 0;
}
</syntaxhighlight>
</source>
 
Keys and values can be any types, but all the keys in an associative array must be of the same type, and the same goes for dependent values.
must be of the same type, and the same for values.
 
You can also loopLooping through all properties and associated values, i.e.and printing them, can be coded as follows:
 
<sourcesyntaxhighlight lang=D"d">
foreach (key, value; phone_book) {
writeln("Number for " ~ key ~ ": " ~ value );
}
</syntaxhighlight>
</source>
 
A property can be removed as follows:
 
<sourcesyntaxhighlight lang=D"d">
phone_book.remove("Sally Smart");
</syntaxhighlight>
</source>
 
===Delphi===
[[Delphi (software)|Delphi]] supports several standard containers, including TDictionary<T>:
 
<syntaxhighlight lang="delphi">
=== [[Borland Delphi|Delphi]] ===
Delphi supports several standard generic containers, including TDictionary<T>:
<source lang=Delphi>
uses
SysUtils,
Line 263:
Writeln(Format('Number for %s: %s',[Entry.Key, Entry.Value]));
end.
</syntaxhighlight>
</source>
 
Versions ofPre-2009 Delphi prior to 2009versions do not offer direct support for associative arrays directly. However,Such youarrays can simulatebe associative arrayssimulated using the TStrings class. Here's an example:
 
<sourcesyntaxhighlight lang=Delphi"delphi">
procedure TForm1.Button1Click(Sender: TObject);
var
Line 290:
DataField.Free;
end;
</syntaxhighlight>
</source>
 
=== [[Erlang (programming language)|Erlang]] ===
[[Erlang (programming language)|Erlang]] offers many approachesways to represent mappings,; twothree of the most common in the standard library are keylists, dictionaries, and dictionariesmaps.
 
====Keylists====
Keylists are lists of tuples, where the first element of each tuple is a key, and the second is a value. Functions for operating on keylists are provided in the <code>lists</code> module.
Keylists are lists of [[tuple]]s, where the first element of each tuple is a key, and the second is a value. Functions for operating on keylists are provided in the <code>lists</code> module.
 
<sourcesyntaxhighlight lang=Erlang"erlang">
PhoneBook = [{"Sally SmartSmith", "555-9999"},
{"John Doe", "555-1212"},
{"J. Random Hacker", "553-1337"}].
</syntaxhighlight>
</source>
 
Accessing an element of the keylist can be done with the <code>lists:keyfind/3</code> function:
 
<sourcesyntaxhighlight lang=Erlang"erlang">
{_, Phone} = lists:keyfind("Sally SmartSmith", 1, PhoneBook),
io:format("Phone number: ~s~n", [Phone]).
</syntaxhighlight>
</source>
 
====Dictionaries====
Dictionaries are implemented in the <code>dict</code> of the standard library. A new dictionary is created using the <code>dict:new/0</code> function and new key/value pairs are stored using the <code>dict:store/3</code> function:
Dictionaries are implemented in the <code>dict</code> module of the standard library. A new dictionary is created using the <code>dict:new/0</code> function and new key/value pairs are stored using the <code>dict:store/3</code> function:
 
<sourcesyntaxhighlight lang=Erlang"erlang">
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).
</syntaxhighlight>
</source>
 
Such a serial initialization would be more idiomatically represented in Erlang with the appropriate function:
 
<sourcesyntaxhighlight lang=Erlang"erlang">
PhoneBook = dict:from_list([{"Sally Smith", "555-9999"},
{"John Doe", "555-1212"},
{"J. Random Hacker", "553-1337"}]).
</syntaxhighlight>
</source>
 
The dictionary can be accessed using the <code>dict:find/2</code> function:
 
<sourcesyntaxhighlight lang=Erlang"erlang">
{ok, Phone} = dict:find("Sally Smith", PhoneBook),
io:format("Phone: ~s~n", [Phone]).
</syntaxhighlight>
</source>
 
In both cases, any Erlang term can be used as the key. Variations include the <code>orddict</code> module, implementing ordered dictionaries, and <code>gb_trees</code>, implementing general balanced trees.
 
====Maps====
=== [[F Sharp (programming language)|F#]] ===
Maps were introduced in OTP 17.0,<ref>{{Cite web|title=Erlang -- maps|url=https://erlang.org/doc/man/maps.html|access-date=2021-03-07|website=erlang.org}}</ref> and combine the strengths of keylists and dictionaries. A map is defined using the syntax <code>#{ K1 => V1, ... Kn => Vn }</code>:
 
<syntaxhighlight lang="erlang">
====Map<'Key,'Value>====
PhoneBook = #{"Sally Smith" => "555-9999",
"John Doe" => "555-1212",
"J. Random Hacker" => "553-1337"}.
</syntaxhighlight>
 
Basic functions to interact with maps are available from the <code>maps</code> module. For example, the <code>maps:find/2</code> function returns the value associated with a key:
The F# runtime provides the <code>Collections.Map<'Key,'Value></code> type, which is an immutable [[AVL tree]].
 
<syntaxhighlight lang="erlang">
=====''Creation''=====
{ok, Phone} = maps:find("Sally Smith", PhoneBook),
io:format("Phone: ~s~n", [Phone]).
</syntaxhighlight>
 
Unlike dictionaries, maps can be pattern matched upon:
 
<syntaxhighlight lang="erlang">
#{"Sally Smith", Phone} = PhoneBook,
io:format("Phone: ~s~n", [Phone]).
</syntaxhighlight>
 
Erlang also provides syntax sugar for functional updates—creating a new map based on an existing one, but with modified values or additional keys:
 
<syntaxhighlight lang="erlang">
PhoneBook2 = PhoneBook#{
% the `:=` operator updates the value associated with an existing key
"J. Random Hacker" := "355-7331",
 
% the `=>` operator adds a new key-value pair, potentially replacing an existing one
"Alice Wonderland" => "555-1865"
}
</syntaxhighlight>
 
===F#===
 
===={{code|Map<'Key,'Value>}}====
At runtime, [[F Sharp (programming language)|F#]] provides the <code>Collections.Map<'Key,'Value></code> type, which is an immutable [[AVL tree]].
 
=====Creation=====
The following example calls the <code>Map</code> constructor, which operates on a list (a semicolon delimited sequence of elements enclosed in square brackets) of tuples (which in F# are comma-delimited sequences of elements).
 
<syntaxhighlight lang="fsharp">
The following example calls the <code>Map</code> constructor on a list (a semicolon delimited sequence of elements enclosed in square brackets) of tuples (which in F# are comma-delimited sequence of elements).
<source lang=fsharp>
let numbers =
[
Line 351 ⟶ 388:
"J. Random Hacker", "555-1337"
] |> Map
</syntaxhighlight>
</source>
 
=====''Access by key''=====
Values can be looked up via one of the <code>Map</code> members, such as its indexer or <code>Item</code> property (which throw an [[Exception handling|exception]] if the key does not exist) or the <code>TryFind</code> function, which returns an [[option type]] with a value of {{code|Some <result>|f#}}, for a successful lookup, or <code>None</code>, for an unsuccessful one. [[Pattern matching]] can then be used to extract the raw value from the result, or a default value can be set.
 
<syntaxhighlight lang="fsharp">
Values can be looked up via one of the <code>Map</code> members, such as its indexer or <code>Item</code> property (which throw an [[Exception handling|exception]] if the key does not exist) or the <code>TryFind</code> function, which returns an [[option type]] with a value of <code>Some <result></code>, for a successful lookup, or <code>None</code>, for an unsuccessful one. [[Pattern matching]] can then be used to extract the raw value, or a default, from the result.
<source lang=fsharp>
let sallyNumber = numbers.["Sally Smart"]
// or
let sallyNumber = numbers.Item("Sally Smart")
</syntaxhighlight>
</source>
<sourcesyntaxhighlight lang=fsharp>
let sallyNumber =
match numbers.TryFind("Sally Smart") with
| Some(number) -> number
| None -> "n/a"
</syntaxhighlight>
</source>
 
In both examples above, the <code>sallyNumber</code> value would contain the string <code>"555-9999"</code>.
 
===={{code|Dictionary<'TKey,'TValue>}}====
Because F# is a .NET language, it also has access to features of the [[.NET Framework]], including the {{code|System.Collections.Generic.Dictionary<'TKey,'TValue>|f#}} type (which is implemented as a [[hash table]]), which is the primary associative array type used in C# and Visual Basic. This type may be preferred when writing code that is intended to operate with other languages on the .NET Framework, or when the performance characteristics of a hash table are preferred over those of an AVL tree.
 
=====Creation=====
Because F# is a .NET language, it also has access to the features of the [[.NET Framework]], including the <code>System.Collections.Generic.Dictionary<'TKey,'TValue></code> type (which is implemented as a [[hash table]]) that is the primary associative array type used in C# and Visual Basic. This type may be preferred when writing code that is intended operate with other languages on the .NET Framework, or when the performance characteristics of a hash table are preferred over those of an AVL tree.
The <code>dict</code> function provides a means of conveniently creating a .NET dictionary that is not intended to be mutated; it accepts a sequence of tuples and returns an immutable object that implements {{code|IDictionary<'TKey,'TValue>|f#}}.
 
<syntaxhighlight lang="fsharp">
=====''Creation''=====
 
The <code>dict</code> function provides a means of conveniently creating a .NET dictionary that is not intended to be mutated; it accepts a sequence of tuples and returns an immutable object that implements <code>IDictionary<'TKey,'TValue></code>.
<source lang=fsharp>
let numbers =
[
Line 383 ⟶ 420:
"J. Random Hacker", "555-1337"
] |> dict
</syntaxhighlight>
</source>
 
When a mutable dictionary is needed, the constructor of <{{code>|System.Collections.Generic.Dictionary<'TKey,'TValue></code>|f#}} can be called directly. See [[#C#|the C# example on this page]] for additional information.
 
<source lang=fsharp>
<syntaxhighlight lang="fsharp">
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"
</syntaxhighlight>
</source>
 
=====''Access by key''=====
<code>IDictionary</code> instances have an indexer that is used in the same way as <code>Map</code>, although the equivalent to <code>TryFind</code> is <code>TryGetValue</code>, which has an output parameter for the sought value and a Boolean return value indicating whether the key was found.
 
<syntaxhighlight lang="fsharp">
<code>IDictionary</code> instances have an indexer that is used in the same way as <code>Map</code>, though the equivalent to <code>TryFind</code> is <code>TryGetValue</code>, which has an output parameter for the sought value and a Boolean return value indicating whether the key was found.
<source lang=fsharp>
let sallyNumber =
let mutable result = ""
if numbers.TryGetValue("Sally Smart", &result) then result else "n/a"
</syntaxhighlight>
</source>
 
F#, however, also allows the function to be called as if it had no output parameter and instead returned a tuple containing its regular return value and the value assigned to the output parameter:
<sourcesyntaxhighlight lang="fsharp">
let sallyNumber =
match numbers.TryGetValue("Sally Smart") with
| true, number -> number
| _ -> "n/a"
</syntaxhighlight>
</source>
 
====Enumeration====
 
A dictionary or map can be enumerated using <code>Seq.map</code>.
 
<source lang=fsharp>
<syntaxhighlight lang=fsharp>
// loop through the collection and display each entry.
numbers |> Seq.map (fun kvp -> printfn "Phone number for %O is %O" kvp.Key kvp.Value)
</syntaxhighlight>
</source>
 
=== [[FoxPro]] ===
[[Visual FoxPro]] implements mapping with the Collection Class.
 
<sourcesyntaxhighlight lang="visualfoxprofoxpro">
mapping = NEWOBJECT("Collection")
mapping.Add("Daffodils", "flower2") && Add(object, key) – key must be character
Line 427 ⟶ 465:
object = mapping("flower2") && returns "Daffodils" (retrieve by key)
object = mapping(1) && returns "Daffodils" (retrieve by index)
</syntaxhighlight>
</source>
 
GetKey returns 0 if the key is not found.
 
===Go===
See Collection in FoxPro Help for all the details.
[[Go (programming language)|Go]] has built-in, language-level support for associative arrays, called "maps". A map's key type may only be a boolean, numeric, string, array, struct, pointer, interface, or channel type.
 
A map type is written: <code>map[keytype]valuetype</code>
=== [[Go (programming language)|Go]] ===
Go has built-in, language-level support for associative arrays, called ''maps''. A map's key type may only be a boolean, numeric, string, array, struct, pointer, interface, or channel type. A map type is written like this: <tt>map[keytype]valuetype</tt>.
 
Adding elements one at a time:
 
<source lang=Go>
<syntaxhighlight lang="go">
phone_book := make(map[string] string) // make an empty map
phone_book["Sally Smart"] = "555-9999"
phone_book["John Doe"] = "555-1212"
phone_book["J. Random Hacker"] = "553-1337"
</syntaxhighlight>
</source>
 
A map literal:
 
<source lang=Go>
<syntaxhighlight lang="go">
phone_book := map[string] string {
"Sally Smart": "555-9999",
Line 451 ⟶ 491:
"J. Random Hacker": "553-1337",
}
</syntaxhighlight>
</source>
 
Iterating through a map:
 
<syntaxhighlight lang="go">
Iterating over a map:
<source lang=Go>
// over both keys and values
for key, value := range phone_book {
Line 464 ⟶ 505:
fmt.Printf("Name: %s\n", key)
}
</syntaxhighlight>
</source>
 
=== [[Haskell (programming language)|Haskell]] ===
The [[Haskell]] programming language's reportprovides only provides one kind of associative container: a list of pairs:
 
<sourcesyntaxhighlight lang="Haskellhaskell">
m = [("Sally Smart", "555-9999"), ("John Doe", "555-1212"), ("J. Random Hacker", "553-1337")]
 
main = print (lookup "John Doe" m)
</syntaxhighlight>
</source>
output:
Just "555-1212"
 
Note that the lookup function returns a "Maybe" value, which is "Nothing" if not found, or "Just ''result{{'' "}} when found.
 
The [[Glasgow Haskell Compiler|GHC]] (GHC), the most commonly used implementation of Haskell, provides two more types of associative containers. Other implementations mightmay also provide these.
 
One is polymorphic functional maps (represented as immutable balanced binary trees):
 
<sourcesyntaxhighlight lang="Haskellhaskell" highlight="1">
import qualified Data.Map as M
 
Line 491 ⟶ 532:
 
main = print (M.lookup "John Doe" m'' :: Maybe String)
</syntaxhighlight>
</source>
output:
Just "555-1212"
Line 499 ⟶ 540:
Finally, a polymorphic hash table:
 
<sourcesyntaxhighlight lang="haskell">
import qualified Data.HashTable as H
 
Line 508 ⟶ 549:
foo <- H.lookup m "John Doe"
print foo
</syntaxhighlight>
</source>
output:
Just "555-1212"
 
Lists of pairs and functional maps both provide a purely functional interface, which is more idiomatic in Haskell. In contrast, hash tables provide an imperative interface in the [[Monad (functional programming)#IO monad|IO monad]].
 
=== [[Java (programming language)|Java]] ===
In [[Java (programming language)|Java]] associative arrays are implemented as "maps";, theywhich are part of the [[Java collections framework]]. Since [[Java Platform, Standard Edition|J2SE]] 5.0 and the introduction of [[generic programming|generics]] into Java, collections can have a type specified; for example, an associative array mappingthat maps strings to strings might be specified as follows:
 
<sourcesyntaxhighlight lang=Java"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");
</syntaxhighlight>
</source>
 
The {{Javadoc:SE|java/util|Map|get(java.lang.Object)|name=get}} method is used to access a key; for example, the value of the expression <code>phoneBook.get("Sally Smart")</code> is <code>"555-9999"</code>. This code uses a hash map to store the associative array, by calling the constructor of the {{Javadoc:SE|java/util|HashMap}} class. However, since the code only uses methods common to the interface {{Javadoc:SE|java/util|Map}}, a self-balancing binary tree could be used by calling the constructor of the {{Javadoc:SE|java/util|TreeMap}} class (which implements the subinterface {{Javadoc:SE|java/util|SortedMap}}), without changing the definition of the <code>phoneBook</code> variable, or the rest of the code, or using other underlying data structures that implement the <code>Map</code> interface.
 
The hash function in Java, used by HashMap and HashSet, is provided by the {{Javadoc:SE|java/lang|Object|hashCode()}} method. Since every class in Java [[Inheritance (object-oriented programming)|inherits]] from {{Javadoc:SE|java/lang|Object}}, every object has a hash function. A class can [[Method overriding (programming)|override]] the default implementation of <code>hashCode()</code> to provide a custom hash function more in accordance with the properties of the object.
This code above uses a hash map to store the associative array, by calling the constructor of the {{Javadoc:SE|java/util|HashMap}} class; however, since the code only uses methods common to the interface {{Javadoc:SE|java/util|Map}}, one could also use a self-balancing binary tree by calling the constructor of the {{Javadoc:SE|java/util|TreeMap}} class (which implements the subinterface {{Javadoc:SE|java/util|SortedMap}}), without changing the definition of the <code>phoneBook</code> variable or the rest of the code, or use a number of other underlying data structures that implement the <code>Map</code> interface.
 
The <code>Object</code> class also contains the {{Javadoc:SE|name=equals(Object)|java/lang|Object|equals(java.lang.Object)}} method, which tests an object for equality with another object. Hashed data structures in Java rely on objects maintaining the following contract between their <code>hashCode()</code> and <code>equals()</code> methods:
The hash function in Java, used by HashMap and HashSet, is provided by the method {{Javadoc:SE|java/lang|Object|hashCode()}}. Since every class in Java [[Inheritance (computer science)|inherits]] from {{Javadoc:SE|java/lang|Object}}, every object has a hash function. A class can [[Method overriding (programming)|override]] the default implementation of <code>hashCode()</code> to provide a custom hash function based on the properties of the object.
 
The <code>Object</code> class also contains the method {{Javadoc:SE|name=equals(Object)|java/lang|Object|equals(java.lang.Object)}} that tests the object for equality with another object. Hashed data structures in Java rely on objects maintaining the following contract between their <code>hashCode()</code> and <code>equals()</code> methods:
 
For two objects ''a'' and ''b'',
 
<source lang=Java>
<syntaxhighlight lang="java">
a.equals(b) == b.equals(a)
if a.equals(b), then a.hashCode() == b.hashCode()
</syntaxhighlight>
</source>
 
In order to maintain this contract, a class that overrides <code>equals()</code> must also override <code>hashCode()</code>, and maybe vice versa, so that <code>hashCode()</code> is based on the same properties (or a subset of the properties) as <code>equals()</code>.
 
A further contract that a hashed data structuresstructure has with the object is that the results of the <code>hashCode()</code> and <code>equals()</code> methods will not change once the object has been inserted into the map. For this reason, it is generally a good practice to base the hash function on [[Immutable object|immutable]] properties of the object.
 
Analogously, TreeMap, and other sorted data structures, requiresrequire that an ordering be defined on the data type. Either the data type must already have defined its own ordering, by implementing the {{Javadoc:SE|java/lang|Comparable}} interface; or a custom {{Javadoc:SE|java/util|Comparator}} must be provided at the time the map is constructed. As with HashMap above, the relative ordering of keys in a TreeMap should not change once they have been inserted into the map.
 
=== [[JavaScript]] ===
JavaScript (and its standardized version: [[ECMAScript]]) is a [[Prototype-based programming|prototype-based]] [[Object-oriented programming|object-oriented]] language. In JavaScript an object is a mapping from property names to values—that is, an associative array with one caveat: since property names are strings, only string and (coerced) integer keys are allowed. Other than that difference, objects also include one feature unrelated to associative arrays: a prototype link to the object they inherit from. Doing a lookup for a property will forward the lookup to the prototype if the object does not define the property itself.
 
[[JavaScript]] (and its standardized version, [[ECMAScript]]) is a [[Prototype-based programming|prototype-based]] [[Object-oriented programming|object-oriented]] language.
An object literal is written as <code>{ property1 : value1, property2 : value2, ... }</code>. For example:
 
====Map and WeakMap====
<source lang=JavaScript>
Modern JavaScript handles associative arrays, using the <code>Map</code> and <code>WeakMap</code> classes. A map does not contain any keys by default; it only contains what is explicitly put into it. The keys and values can be any type (including functions, objects, or any primitive).
var myObject = {
 
"Sally Smart" : "555-9999",
=====Creation=====
"John Doe" : "555-1212",
A map can be initialized with all items during construction:
"J. Random Hacker" : "553-1337"
 
<syntaxhighlight lang="javascript">
const phoneBook = new Map([
["Sally Smart", "555-9999"],
["John Doe", "555-1212"],
["J. Random Hacker", "553-1337"],
]);
</syntaxhighlight>
 
Alternatively, you can initialize an empty map and then add items:
 
<syntaxhighlight lang="javascript">
const phoneBook = new Map();
phoneBook.set("Sally Smart", "555-9999");
phoneBook.set("John Doe", "555-1212");
phoneBook.set("J. Random Hacker", "553-1337");
</syntaxhighlight>
 
=====Access by key=====
Accessing an element of the map can be done with the <code>get</code> method:
 
<syntaxhighlight lang="javascript">
const sallyNumber = phoneBook.get("Sally Smart");
</syntaxhighlight>
 
In this example, the value <code>sallyNumber</code> will now contain the string "555-9999".
 
=====Enumeration=====
The keys in a map are ordered. Thus, when iterating through it, a map object returns keys in order of insertion. The following demonstrates enumeration using a for-loop:
 
<syntaxhighlight lang="javascript">
// loop through the collection and display each entry.
for (const [name, number] of phoneBook) {
console.log(`Phone number for ${name} is ${number}`);
}
</syntaxhighlight>
 
A key can be removed as follows:
 
<syntaxhighlight lang="javascript">
phoneBook.delete("Sally Smart");
</syntaxhighlight>
 
====Object====
An object is similar to a map—both let you set keys to values, retrieve those values, delete keys, and detect whether a value is stored at a key. For this reason (and because there were no built-in alternatives), objects historically have been used as maps.
 
However, there are important differences that make a map preferable in certain cases. In JavaScript an object is a mapping from property names to values—that is, an associative array with one caveat: the keys of an object must be either a string or a symbol (native objects and primitives implicitly converted to a string keys are allowed). Objects also include one feature unrelated to associative arrays: an object has a prototype, so it contains default keys that could conflict with user-defined keys. So, doing a lookup for a property will point the lookup to the prototype's definition if the object does not define the property.
 
An object literal is written as <code>{ property1: value1, property2: value2, ... }</code>. For example:
 
<syntaxhighlight lang="javascript">
const myObject = {
"Sally Smart": "555-9999",
"John Doe": "555-1212",
"J. Random Hacker": "553-1337",
};
</syntaxhighlight>
</source>
 
To prevent the lookup from using the prototype's properties, you can use the <code>Object.setPrototypeOf</code> function:
 
<syntaxhighlight lang=JavaScript>
Object.setPrototypeOf(myObject, null);
</syntaxhighlight>
 
As of ECMAScript 5 (ES5), the prototype can also be bypassed by using <code>Object.create(null)</code>:
 
<syntaxhighlight lang=JavaScript>
const myObject = Object.create(null);
 
Object.assign(myObject, {
"Sally Smart": "555-9999",
"John Doe": "555-1212",
"J. Random Hacker": "553-1337",
});
</syntaxhighlight>
 
If the property name is a valid identifier, the quotes can be omitted, e.g.:
 
<sourcesyntaxhighlight lang=JavaScript>
varconst myOtherObject = { foo : 42, bar : false };
</syntaxhighlight>
</source>
 
Lookup is written using property -access notation, either square brackets, which always workswork, or dot notation, which only works for identifier keys:
 
<sourcesyntaxhighlight lang=JavaScript>
myObject["John Doe"]
myOtherObject.foo
</syntaxhighlight>
</source>
 
You can also loop through all enumerable properties and associated values as follows (a for-in loop):
 
<sourcesyntaxhighlight lang=JavaScript>
for (varconst property in myObject) {
var const value = myObject[property];
alert console.log("`myObject[" + ${property + "}] = " + ${value}`);
}
</syntaxhighlight>
</source>
 
Or (a for-of loop):
 
<syntaxhighlight lang=JavaScript>
for (const [property, value] of Object.entries(myObject)) {
console.log(`${property} = ${value}`);
}
</syntaxhighlight>
 
A property can be removed as follows:
 
<sourcesyntaxhighlight lang=JavaScript>
delete myObject["Sally Smart"];
</syntaxhighlight>
</source>
 
As mentioned before, properties are strings. However,and symbols. sinceSince every native object and primitive can be implicitly converted to a string, you can do:
 
<sourcesyntaxhighlight lang=JavaScript>
myObject[1] // key is "1"; note that myObject[1] == myObject['"1'"]
myObject[['"a'",' "b'"]] // key is "a,b"
myObject[{ toString:function() { return '"hello world'"; } }] // key is "hello world"
</syntaxhighlight>
</source>
 
In modern JavaScript it's considered bad form to use the Array type as an associative array. Consensus is that the Object type and <code>Map</code>/<code>WeakMap</code> classes are best for this purpose. The reasoning behind this is that if Array is extended via prototype and Object is kept pristine, for and for-in loops will work as expected on associative 'arrays'. This issue has been brought to the fore by the popularity of JavaScript frameworks that make heavy and sometimes indiscriminate use of prototypes to extend JavaScript's inbuilt types.
Any object, including built-in objects such as Array, can be dynamically extended with new properties. For example:
 
<source lang=JavaScript>
Array.prototype.removeAllObjects = function () {
/* ... */
}
</source>
 
In modern JavaScript it's considered bad form to use the Array type as an associative array. Consensus is that the Object type is best for this purpose. The reasoning behind this is that if Array is extended via prototype and Object is kept pristine, 'for(in)' loops will work as expected on associative 'arrays'. This issue has been drawn into focus by the popularity of JavaScript frameworks that make heavy and sometimes indiscriminate use of prototype to extend JavaScript's inbuilt types.
 
See [http://blog.metawrap.com/2006/05/30/june-6th-is-javascript-array-and-object-prototype-awareness-day/ JavaScript Array And Object Prototype Awareness Day] for more information on the issue.
 
=== [[Julia (programming language)|Julia]] ===
 
In [[Julia (programming language)|Julia]], the following operations manage associative arrays.
 
Declare dictionary:
<sourcesyntaxhighlight lang="julia">
phonebook = Dict( "Sally Smart" => "555-9999", "John Doe" => "555-1212", "J. Random Hacker" => "555-1337" )
</syntaxhighlight>
</source>
 
Access element:
 
<syntaxhighlight lang="julia">
phonebook["Sally Smart"]
phonebook["Sally Smart"]
</syntaxhighlight>
 
Add element:
<syntaxhighlight lang="julia">
 
phonebook["New Contact"] = "555-2222"
</syntaxhighlight>
 
Delete element:
<syntaxhighlight lang="julia">
delete!(phonebook, "Sally Smart")
</syntaxhighlight>
 
Get keys and values as [[Iterator#Implicit iterators|iterables]]:
delete!(phonebook, "Sally Smart")
<syntaxhighlight lang="julia">
keys(phonebook)
values(phonebook)
</syntaxhighlight>
 
===KornShell 93, and compliant shells===
Get keys and values as iterables:
In [[Korn Shell|KornShell]] 93, and compliant shells (ksh93, bash4...), the following operations can be used with associative arrays.
 
keys(phonebook)
values(phonebook)
 
=== [[Korn Shell|KornShell]] 93 (and compliant shells: ksh93, bash4...) ===
<!-- Tested in ksh93 r -->
Definition:
<syntaxhighlight lang="ksh">
typeset -A phonebook; # ksh93; in bash4+, "typeset" is a synonym of the more preferred "declare", which works identically in this case
phonebook=(["Sally Smart"]="555-9999" ["John Doe"]="555-1212" ["[[J. Random Hacker]]"]="555-1337");
</syntaxhighlight>
 
Definition:
<source lang="ksh">
typeset -A phonebook; # ksh93
declare -A phonebook; # bash4
phonebook=(["Sally Smart"]="555-9999" ["John Doe"]="555-1212" ["[[J. Random Hacker]]"]="555-1337");
</source>
Dereference:
<sourcesyntaxhighlight lang="ksh">
${phonebook["John Doe"]};
</syntaxhighlight>
</source>
 
=== [[Lisp programming language|Lisp]] ===
[[Lisp programming language|Lisp]] was originally conceived as a "LISt Processing" language, and one of its most important data types is the linked list, which can be treated as an [[association list]] ("alist").
 
<sourcesyntaxhighlight lang=Lisp>
'(("Sally Smart" . "555-9999")
("John Doe" . "555-1212")
("J. Random Hacker" . "553-1337"))
</syntaxhighlight>
</source>
 
The syntax <code>(x . y)</code> is used to indicate a [[cons|<code>cons</code>ed]] pair. Keys and values need not be the same type within an alist. Lisp and [[Scheme (programming language)|Scheme]] provide operators such as <code>assoc</code> to manipulate alists in ways similar to associative arrays.
 
A set of operations specific to the handling of association lists exists for [[Common Lisp]], each of these working non-destructively.
 
To add an entry the <code>acons</code> function is employed, creating and returning a new association list. An association list in Common Lisp mimicks a stack, that is, adheres to the last-in-first-out (LIFO) principle, and hence prepends to the list head.
 
<sourcesyntaxhighlight lang=Lisp>
(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)))
</syntaxhighlight>
</source>
 
This function can actually be construed as aan convenience accommodatingaccommodation for <code>cons</code> operations.[<ref>{{cite web |title=Common Lisp the Language, 2nd Edition: 15.6. Association Lists |url=https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node153.html] |website=Carnegie Mellon University |access-date=3 August 2020}}</ref>
 
<sourcesyntaxhighlight lang=Lisp>
;; The effect of
;; (cons (cons KEY VALUE) ALIST)
Line 673 ⟶ 794:
(let ((phone-book '(("Sally Smart" . "555-9999") ("John Doe" . "555-1212"))))
(cons (cons "J. Random Hacker" "555-1337") phone-book))
</syntaxhighlight>
</source>
 
Of course, the destructive <code>push</code> operation also allows inserting entries into an association list, an entry having to constitute a key-value cons in order to retain the mapping's validity.
 
<sourcesyntaxhighlight lang=Lisp>
(push (cons "Dummy" "123-4567") phone-book)
</syntaxhighlight>
</source>
 
Searching for an entry by its key is performed via <code>assoc</code>, which might be configured regardingfor the test predicate and direction, especially searching from the association list from its end to its front. The result, if positive, constitutesreturns the entire entry cons, not only its value. Failure to obtain a matching key ledsleads to a return of the <code>NIL</code> value.
 
<sourcesyntaxhighlight lang=Lisp>
(assoc "John Doe" phone-book :test #'string=)
</syntaxhighlight>
</source>
 
Two generalizations of <code>assoc</code> exist: <code>assoc-if</code> expects a predicate function testingthat tests each entry's key instead of directly specifying the desiderated key, returning the first entry for which the predicate produces a non-<code>NIL</code> value upon invocation. <code>assoc-if-not</code> inverts the logic, accepting the same arguments, but replying withreturning the first entry generating <code>NIL</code>.
 
<sourcesyntaxhighlight lang=Lisp>
;; Find the first entry whose key equals "John Doe".
(assoc-if
Line 701 ⟶ 822:
(member key '("Sally Smart" "John Doe") :test #'string=))
phone-book)
</syntaxhighlight>
</source>
 
The inverse process, the detection of an entry by its value, utilizes <code>rassoc</code>.
 
<sourcesyntaxhighlight lang=Lisp>
;; Find the first entry with a value of "555-9999".
;; We test the entry string values with the "string=" predicate.
(rassoc "555-9999" phone-book :test #'string=)
</syntaxhighlight>
</source>
 
The corresponding generalizations <code>rassoc-if</code> and <code>rassoc-if-not</code> exist.
 
<sourcesyntaxhighlight lang=Lisp>
;; Finds the first entry whose value is "555-9999".
(rassoc-if
Line 725 ⟶ 846:
(string= value "555-9999"))
phone-book)
</syntaxhighlight>
</source>
 
All of the above explicatedprevious entry search functions can be replaced by general list-centric variants, thatsuch is,as <code>find</code>, <code>find-if</code>, <code>find-if-not</code>, as well as pertinent functions like <code>position</code> and its derivates.
 
<sourcesyntaxhighlight lang=Lisp>
;; Find an entry with the key "John Doe" and the value "555-1212".
(find (cons "John Doe" "555-1212") phone-book :test #'equal)
</syntaxhighlight>
</source>
 
Deletion, lacking a specific counterpart, is based upon the list facilities, including destructive ones.
 
<sourcesyntaxhighlight lang=Lisp>
;; Create and return an alist without any entry whose key equals "John Doe".
(remove-if
Line 742 ⟶ 863:
(string= (car entry) "John Doe"))
phone-book)
</syntaxhighlight>
</source>
 
Iteration is accomplished bywith the aid of any function expectingthat expects a list.
 
<sourcesyntaxhighlight lang=Lisp>
;; Iterate via "map".
(map NIL
Line 758 ⟶ 879:
(destructuring-bind (key . value) entry
(format T "~&~s => ~s" key value)))
</syntaxhighlight>
</source>
 
BeingThese a particularlybeing structured listlists, processing and transformation operations can be applied without constraints.
 
<sourcesyntaxhighlight lang=Lisp>
;; Return a vector of the "phone-book" values.
(map 'vector #'cdr phone-book)
Line 772 ⟶ 893:
(cons (reverse key) (reverse value))))
phone-book)
</syntaxhighlight>
</source>
 
Because of their linear nature, alists are used for relatively small sets of data. [[Common Lisp]] also supports a [[hash table]] data type, and for [[Scheme (programming language)|Scheme]] they are implemented in [[Scheme Requests for Implementation|SRFI]] 69. Hash tables have greater overhead than alists, but provide much faster access when there are many elements. A further characteristic mark lies inis the fact that Common Lisp hash tables do not, as opposed to association lists, maintain the order of entry insertion.
 
Common Lisp hash tables are constructed via the <code>make-hash-table</code> function, whose arguments encompass, among other configurations, a predicate to test the entry key against. While tolerating arbitrary objects, even of heterogeneity inwithin a single hash table instance, the specification of this key <code>:test</code> function confinesis theconfined to distinguishable entities: Thethe Common Lisp standard only mandates the support of <code>eq</code>, <code>eql</code>, <code>equal</code>, and <code>equalp</code>, yet designating additional or custom operations as permissive for concrete implementations.
 
<sourcesyntaxhighlight lang=Lisp>
(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"))
</syntaxhighlight>
</source>
 
The <code>gethash</code> function permits obtention ofobtaining the value associated with a key.
 
<sourcesyntaxhighlight lang=Lisp>
(gethash "John Doe" phone-book)
</syntaxhighlight>
</source>
 
Additionally, an optionala default value for the case of an absent key may be specified.
 
<sourcesyntaxhighlight lang=Lisp>
(gethash "Incognito" phone-book 'no-such-key)
</syntaxhighlight>
</source>
 
An invocation of <code>gethash</code> actually returns two values: the value or substitute value for the key and a boolean indicator, resolving toreturning <code>T</code> if the hash table contains the key and <code>NIL</code> to signal its absence.
 
<sourcesyntaxhighlight lang=Lisp>
(multiple-value-bind (value contains-key) (gethash "Sally Smart" phone-book)
(if contains-key
(format T "~&The associated value is: ~s" value)
(format T "~&The key could not be found.")))
</syntaxhighlight>
</source>
 
Use <code>remhash</code> for deleting the entry associated with a key.
 
<sourcesyntaxhighlight lang=Lisp>
(remhash "J. Random Hacker" phone-book)
</syntaxhighlight>
</source>
 
<code>clrhash</code> completely empties the complete hash table.
 
<sourcesyntaxhighlight lang=Lisp>
(clrhash phone-book)
</syntaxhighlight>
</source>
 
The dedicated <code>maphash</code> function isspecializes specialized onin iterating hash tables.
 
<sourcesyntaxhighlight lang=Lisp>
(maphash
#'(lambda (key value)
(format T "~&~s => ~s" key value))
phone-book)
</syntaxhighlight>
</source>
 
Alternatively, the <code>loop</code> construct makes provisions for iterations, either over thethrough keys, values, or the conjunctions of both.
 
<sourcesyntaxhighlight lang=Lisp>
;; Iterate the keys and values of the hash table.
(loop
Line 840 ⟶ 961:
for value being the hash-values of phone-book
do (print value))
</syntaxhighlight>
</source>
 
A further option comprises the invocation ofinvokes <code>with-hash-table-iterator</code>, an iterator-creating macro, the processing of which is intended to be driven by the caller.
 
<sourcesyntaxhighlight lang=Lisp>
(with-hash-table-iterator (entry-generator phone-book)
(loop do
Line 851 ⟶ 972:
(format T "~&~s => ~s" key value)
(loop-finish)))))
</syntaxhighlight>
</source>
 
It is easy to construct composite abstract data types in Lisp, using structures and/or the object-oriented programming features, in conjunction with lists, arrays, and hash tables.
 
=== [[LPC (programming language)|LPC]] ===
[[LPC (programming language)|LPC]] implements associative arrays as a fundamental type known as either "map" or "mapping", depending on the driver. The keys and values can be of any type. A mapping literal is written as <code>([ key_1 : value_1, key_2 : value_2 ])</code>. Procedural usecode looks like:
 
<sourcesyntaxhighlight lang=C>
mapping phone_book = ([]);
phone_book["Sally Smart"] = "555-9999";
phone_book["John Doe"] = "555-1212";
phone_book["J. Random Hacker"] = "555-1337";
</syntaxhighlight>
</source>
 
Mappings are accessed for reading using the indexing operator in the same way as they are for writing, as shown above. So phone_book["Sally Smart"] would return the string "555-9999", and phone_book["John Smith"] would return 0. Testing for presence is done using the function member(), e.g. <code>if(member(phone_book, "John Smith")) write("John Smith is listed.\n");</code>
 
Deletion is accomplished using a function called either m_delete() or map_delete(), depending on the driver, used like: <code>m_delete(phone_book, "Sally Smart");</code>
 
LPC drivers of the "[[LPMud#Amylaar"|Amylaar]] family implement multivalued mappings using a secondary, numeric index. (Driversother drivers of the [[MudOS]] family do not support multivalued mappings.) Example syntax:
 
<sourcesyntaxhighlight lang=C>
mapping phone_book = ([:2]);
phone_book["Sally Smart", 0] = "555-9999";
Line 879 ⟶ 1,000:
phone_book["J. Random Hacker", 0] = "555-1337";
phone_book["J. Random Hacker", 1] = "77 Massachusetts Avenue";
</syntaxhighlight>
</source>
 
LPC drivers modern enough to support a foreach() construct allowuse iterationit overto iterate through their mapping types using it.
 
===Lua===
In [[Lua programming language|Lua]], "table" is a fundamental type that can be used either as an array (numerical index, fast) or as an associative array.
 
=== [[Lua programming language|Lua]] ===
In Lua, table is a fundamental type that can be used either as array (numerical index, fast) or as associative array.
The keys and values can be of any type, except nil. The following focuses on non-numerical indexes.
 
A table literal is written as <code>{ value, key = value, [index] = value, ["non id string"] = value }</code>. For example:
 
<sourcesyntaxhighlight lang=Lua>
phone_book = {
["Sally Smart"] = "555-9999",
Line 903 ⟶ 1,025:
-- Table and function (and other types) can also be used as keys
}
</syntaxhighlight>
</source>
 
If the key is a valid identifier (not a keywordreserved word), the quotes can be omitted. TheyIdentifiers are case sensitive.
 
Lookup is written using either square brackets, which always works, or dot notation, which only works for identifier keys:
 
<sourcesyntaxhighlight lang=Lua>
print(aTable["John Doe"](45))
x = aTable.subTable.k
</syntaxhighlight>
</source>
 
You can also loop through all keys and associated values with iterators or for -loops:
 
<sourcesyntaxhighlight lang=Lua>
simple = { [true] = 1, [false] = 0, [3.14] = math.pi, x = 'x', ["!"] = 42 }
function FormatElement(key, value)
Line 932 ⟶ 1,054:
until k == nil
print""
</syntaxhighlight>
</source>
 
An entry can be removed by setting it to nil:
 
<sourcesyntaxhighlight lang=Lua>
simple.x = nil
</syntaxhighlight>
</source>
 
Likewise, you can overwrite values or add them:
 
<sourcesyntaxhighlight lang=Lua>
simple['%'] = "percent"
simple['!'] = 111
</syntaxhighlight>
</source>
 
===Mathematica and Wolfram Language===
 
[[Mathematica]] and [[Wolfram Language]] use the Association expression to represent associative arrays.<ref>{{cite web|url=https://reference.wolfram.com/language/ref/Association.html|title=Association (<-...->)—Wolfram Language Documentation|website=reference.wolfram.com}}</ref>
 
<syntaxhighlight lang="mathematica">
phonebook = <| "Sally Smart" -> "555-9999",
"John Doe" -> "555-1212",
"J. Random Hacker" -> "553-1337" |>;
</syntaxhighlight>
 
To access:<ref>{{cite web|url=https://reference.wolfram.com/language/ref/Key.html|title=Key—Wolfram Language Documentation|website=reference.wolfram.com}}</ref>
 
<syntaxhighlight lang="mathematica">
phonebook[[Key["Sally Smart"]]]
</syntaxhighlight>
 
If the keys are strings, the Key keyword is not necessary, so:
 
<syntaxhighlight lang="mathematica">
=== [[Mathematica]] and [[Wolfram Language]] ===
phonebook[["Sally Smart"]]
</syntaxhighlight>
 
MathematicaTo useslist the Associationkeys:<ref>{{cite web|url=https://reference.wolfram.com/language/ref/AssociationKeys.html|title=Association ( <-...-> )—WolframKeys—Wolfram Language Documentation|website=reference.wolfram.com}}</ref> expressionand tovalues<ref>{{cite representweb|url=https://reference.wolfram.com/language/ref/Values.html|title=Values—Wolfram associativeLanguage arraysDocumentation|website=reference.wolfram.com}}</ref>
<source lang="mathematica">
phonebook = <| "Sally Smart" -> "555-9999",
"John Doe" -> "555-1212",
"J. Random Hacker" -> "553-1337" |>;
</source>
To access<ref>{{cite web|url=https://reference.wolfram.com/language/ref/Key.html|title=Key—Wolfram Language Documentation|website=reference.wolfram.com}}</ref>
<source lang="mathematica">
phonebook[[Key["Sally Smart"]]]
</source>
If the keys are strings, the ''Key'' keyword is not necessary, so:
<source lang="mathematica">
phonebook[["Sally Smart"]]
</source>
To list keys<ref>{{cite web|url=https://reference.wolfram.com/language/ref/Keys.html|title=Keys—Wolfram Language Documentation|website=reference.wolfram.com}}</ref> and values<ref>{{cite web|url=https://reference.wolfram.com/language/ref/Values.html|title=Values—Wolfram Language Documentation|website=reference.wolfram.com}}</ref>
 
Keys[phonebook]
Values[phonebook]
 
=== [[MUMPS]] ===
In [[MUMPS]] every array is an associative array. The built-in, language-level, direct support for associative arrays
applies to private, process-specific arrays stored in memory called "locals" as well as to the permanent, shared, global arrays stored on disk which are available concurrently byto multiple jobs. The name for globals is preceded by the circumflex "^" to distinguish itthem from local variable namesvariables.
 
SET ^phonebook("Sally Smart")="555-9999" ;; storing permanent data
SET phonebook("John Doe")="555-1212" ;; storing temporary data
SET phonebook("J. Random Hacker")="553-1337" ;; storing temporary data
MERGE ^phonebook=phonebook ;; copying temporary data into permanent data
 
To accessAccessing the value of an element, simply requires using the name with the subscript:
 
WRITE "Phone Number :",^phonebook("Sally Smart"),!
Line 986 ⟶ 1,114:
FOR S NAME=$ORDER(^phonebook(NAME)) QUIT:NAME="" WRITE NAME," Phone Number :",^phonebook(NAME),!
 
=== [[Objective-C]] (Cocoa/GNUstep) ===
[[Cocoa (API)|Cocoa]] and [[GNUstep]], written in [[Objective-C]], handle associative arrays using <code>NSMutableDictionary</code> (a mutable version of <code>NSDictionary</code>) class cluster. This class allows assignments between any two objects to be made. A copy of the key object is made before it is inserted into <code>NSMutableDictionary</code>, therefore the keys must conform to the <code>NSCopying</code> protocol. When being inserted to a dictionary, the value object receives a retain message to increase its reference count. The value object will receive the release message when it will be deleted from the dictionary (botheither explicitly or by adding to the dictionary a different object with the same key).
 
<sourcesyntaxhighlight lang=ObjC>
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"];
</syntaxhighlight>
</source>
 
To access assigned objects, this command may be used:
 
<sourcesyntaxhighlight lang=ObjC>
id anObject = [aDictionary objectForKey:@"Sally Smart"];
</syntaxhighlight>
</source>
 
All keys or values can be simply enumerated using <code>NSEnumerator</code>:
 
<sourcesyntaxhighlight lang=ObjC>
NSEnumerator *keyEnumerator = [aDictionary keyEnumerator];
id key;
Line 1,011 ⟶ 1,139:
// ... process it here ...
}
</syntaxhighlight>
</source>
 
OnIn Mac OS X 10.5+ and iPhone OS, dictionary keys can also be enumerated more concisely using thisthe [<code>NSFastEnumeration</code> construct:<ref>{{cite web |title=NSFastEnumeration Protocol Reference |url=https://developer.apple.com/documentation/Cocoa/Reference/NSFastEnumeration_protocol/ NSFastEnumeration]|date=2011 construct|archive-url=https://web.archive.org/web/20160313082808/https://developer.apple.com/library/mac/documentation/Cocoa/Reference/NSFastEnumeration_protocol/ |archive-date=13 March 2016 |website=Mac Developer Library |access-date=3 August 2020}}</ref>
 
<sourcesyntaxhighlight lang=ObjC>
for (id key in aDictionary) {
// ... process it here ...
}
</syntaxhighlight>
</source>
 
What is even more practical, structured data graphs may be easily created using [[Cocoa (API)|Cocoa]], especially <code>NSDictionary</code> (<code>NSMutableDictionary</code>). This can be illustrated with this compact example:
 
<sourcesyntaxhighlight lang=ObjC>
NSDictionary *aDictionary =
[NSDictionary dictionaryWithObjectsAndKeys:
Line 1,034 ⟶ 1,162:
nil], @"hackers",
nil];
</syntaxhighlight>
</source>
 
And relevantRelevant fields can be quickly accessed using key paths:
 
<sourcesyntaxhighlight lang=ObjC>
id anObject = [aDictionary valueForKeyPath:@"students.Sally Smart"];
</syntaxhighlight>
</source>
 
=== [[OCaml]] ===
The [[OCaml]] programming language provides three different associative containers. The simplest is a list of pairs:
 
<sourcesyntaxhighlight lang=OCaml>
# let m = [
"Sally Smart", "555-9999";
Line 1,057 ⟶ 1,185:
# List.assoc "John Doe" m;;
- : string = "555-1212"
</syntaxhighlight>
</source>
 
The second is a polymorphic hash table:
 
<sourcesyntaxhighlight lang=OCaml>
# let m = Hashtbl.create 3;;
val m : ('_a, '_b) Hashtbl.t = <abstr>
Line 1,070 ⟶ 1,198:
# Hashtbl.find m "John Doe";;
- : string = "555-1212"
</syntaxhighlight>
</source>
 
The code above uses OCaml's default hash function <code>Hashtbl.hash</code>, which is defined automatically for all types. If you wanted toTo use youra ownmodified hash function, you can use the functor interface <code>Hashtbl.Make</code> to create a module, likesuch as with <code>Map</code> below.
 
Finally, functional maps (represented as immutable balanced binary trees):
 
<sourcesyntaxhighlight lang=OCaml>
# module StringMap = Map.Make(String);;
...
Line 1,085 ⟶ 1,213:
# StringMap.find "John Doe" m;;
- : string = "555-1212"
</syntaxhighlight>
</source>
 
Note that in order to use <code>Map</code>, you have to provide the functor <code>Map.Make</code> with a module which defines the key type and the comparison function. The third-party library ExtLib provides a polymorphic version of functional maps, called [<code>PMap</code>,<ref>{{cite web |title=Module PMap |url=http://ocaml-extlib.googlecode.com/svn/doc/apiref/PMap.html |date=2008 |archive-url=https://web.archive.org/web/20081211233540/http://ocaml-extlib.googlecode.com/svn/doc/apiref/PMap.html PMap],|archive-date=11 whereDecember you2008 provide|website=Ocaml-extlib the|access-date=3 comparisonAugust function2020}}</ref> whenwhich creatingis given a comparison function theupon mapcreation.
 
Lists of pairs and functional maps both provide a purely functional interface. InBy contrast, hash tables provide an imperative interface. For many operations, hash tables are significantly faster than lists of pairs and functional maps.
 
=== [[OptimJ]] ===
{{RefimproveMore citations needed section|date=February 2011}}
The [[OptimJ]] programming language is an extension of Java 5. As javadoes Java, Optimj provides maps.; But,but OptimJ also provides true associative arrays:. javaJava arrays are indexed with 0non-basednegative integers; associative arrays are indexed with any collectiontype of keyskey.
 
<sourcesyntaxhighlight lang=Java>
String[String] phoneBook = {
"Sally Smart" -> "555-9999",
"John Doe" -> "555-1212",
"J. Random Hacker" -> "553-1337"
};
 
Line 1,106 ⟶ 1,234:
 
// iterate over the values
for (String number : phoneBook) {
System.out.println(number);
}
 
Line 1,113 ⟶ 1,241:
 
// iterate over the keys
for (String name : phoneBook.keys) {
System.out.println(name + " -> " + phoneBook[name]);
}
// phoneBook[name] access a value by a key (it looks like java array access)
// i.e. phoneBook["John Doe"] returns "555-1212"
 
</syntaxhighlight>
</source>
 
Of course, it is possible to define multi-dimensional arrays, to mix javaJava arrayarrays and associative arrays, to mix maps and associative arrays.
 
<sourcesyntaxhighlight lang=Java>
int[String][][double] a;
java.util.Map<String[Object], Integer> b;
</syntaxhighlight>
</source>
 
=== [[Perl 5]] ===
[[Perl 5]] has built-in, language-level support for associative arrays. Modern Perl vernacular refers to associative arrays as ''hashes''; the term ''associative array'' is found in older documentation, but is considered somewhat archaic. Perl 5 hashes are flat: keys are strings and values are scalars. However, values may be [[reference (computer science)|references]] to arrays or other hashes, and the standard Perl 5 module Tie::RefHash enables hashes to be used with reference keys.
 
A hash variable is marked by a <code>%</code> [[sigil (computer programming)|sigil]], to distinguish it from scalar, array, and other data types. A hash literal is a key-value list, with the preferred form using Perl's <code>=&gt;</code> token, which is mostly semantically mostly identical to the comma and makes the key-value association clearer:
 
<sourcesyntaxhighlight lang=Perl>
my %phone_book = (
'Sally Smart' => '555-9999',
Line 1,139 ⟶ 1,267:
'J. Random Hacker' => '553-1337',
);
</syntaxhighlight>
</source>
 
Accessing a hash element uses the syntax <code>$hash_name{$key}</code> – the key is surrounded by ''[[Bracket#Curly bracket|curly braces'']] and the hash name is prefixed by a <code>$</code>, indicating that the hash element itself is a ''scalar'' value, even though it is part of a hash. The value of <code>$phone_book{'John Doe'}</code> is <code>'555-1212'</code>. The <code>%</code> sigil is only used when referring to the hash as a whole, such as when asking for <code>keys %phone_book</code>.
 
The list of keys and values can be extracted using the built-in functions <code>keys</code> and <code>values</code>, respectively. So, for example, to print all the keys of a hash:
 
<sourcesyntaxhighlight lang=Perl>
foreach $name (keys %phone_book) {
print $name, "\n";
}
</syntaxhighlight>
</source>
 
One can iterate through (key, value) pairs using the <code>each</code> function:
 
<sourcesyntaxhighlight lang=Perl>
while (($name, $number) = each %phone_book) {
print 'Number for ', $name, ': ', $number, "\n";
}
</syntaxhighlight>
</source>
 
A hash ''"reference''", which is a scalar value that points to a hash, is specified in literal form using curly braces as delimiters, with syntax otherwise similar to specifying a hash literal:
 
<sourcesyntaxhighlight lang=Perl>
my $phone_book = {
'Sally Smart' => '555-9999',
Line 1,167 ⟶ 1,295:
'J. Random Hacker' => '553-1337',
};
</syntaxhighlight>
</source>
 
Values in a hash reference are accessed using the dereferencing operator:
 
<sourcesyntaxhighlight lang=Perl>
print $phone_book->{'Sally Smart'};
</syntaxhighlight>
</source>
 
When the hash contained in the hash reference needs to be referred to as a whole, as with the <code>keys</code> function, the syntax is as follows:
 
<sourcesyntaxhighlight lang=Perl>
foreach $name (keys %{$phone_book}) {
print 'Number for ', $name, ': ', $phone_book->{$name}, "\n";
}
</syntaxhighlight>
</source>
 
===Perl [[Raku6 (programming languageRaku)|Raku]] ===
[[Raku (programming language)|Perl 6]], renamed as "Raku", also has built-in, language-level support for associative arrays, which are referred to as ''hashes'' or as objects performing the ''Associative''"associative" role. ByAs defaultin Perl 5, Perl 6 default hashes are flat: keys are strings and values are scalars. One can define a ''hash'' to not coerce all keys to strings automatically: these are referred to as ''"object hashes''", because the keys of such hashes remain the original object rather than a stringification thereof.
 
A hash variable is typically marked by a <code>%</code> [[sigil (computer programming)|sigil]], to visually distinguish it from scalar, array, and other data types, and to define its behaviour towards iteration. A hash literal is a key-value list, with the preferred form using Perl's <code>=&gt;</code> token, which makes the key-value association clearer:
 
<sourcesyntaxhighlight lang=Perl6>
my %phone-book =
'Sally Smart' => '555-9999',
Line 1,194 ⟶ 1,322:
'J. Random Hacker' => '553-1337',
;
</syntaxhighlight>
</source>
 
Accessing a hash element uses the syntax <code>%hash_name{$key}</code> – the key is surrounded by ''curly braces'' and the hash name (note that the sigil does '''not''' change, contrary to [[Perl 5]]). The value of <code>%phone-book{'John Doe'}</code> is <code>'555-1212'</code>.
 
The list of keys and values can be extracted using the built-in functions <code>keys</code> and <code>values</code>, respectively. So, for example, to print all the keys of a hash:
 
<sourcesyntaxhighlight lang=Perl6>
for %phone-book.keys -> $name {
say $name;
}
</syntaxhighlight>
</source>
 
By default, when iterating overthrough a ''hash'', one gets key/valuekey–value ''Pair''spairs.
 
<sourcesyntaxhighlight lang=Perl6>
for %phone-book -> $entry {
say "Number for $entry.key(): $entry.value()"; # using extended interpolation features
}
</syntaxhighlight>
</source>
 
It's is also possible to get alternating key values and value values by using the ''<code>kv''</code> method:
 
<sourcesyntaxhighlight lang=Perl6>
for %phone-book.kv -> $name, $number {
say "Number for $name: $number";
}
</syntaxhighlight>
</source>
 
[[Raku (programming language)|Raku]] doesn't have any references. Hashes can be passed around as single parameters that doare not get flattened. If you want to make sure that a subroutine only accepts hashes, use the ''%'' sigil in the ''Signature''.
 
<sourcesyntaxhighlight lang=Perl6>
sub list-phone-book(%pb) {
for %pb.kv -> $name, $number {
Line 1,231 ⟶ 1,359:
}
list-phone-book(%phone-book);
</syntaxhighlight>
</source>
 
CompliantIn compliance with the sense of [[gradual typing]], hashes may be subjected to type constraints, confining thea set of valid keys to a certain type.
 
<sourcesyntaxhighlight lang=Perl6>
# Define a hash whose keys may only be integer numbers ("Int" type).
my %numbersWithNames{Int};
Line 1,244 ⟶ 1,372:
# This will cause an error, as strings as keys are invalid.
%numbersWithNames.push("key" => "two");
</syntaxhighlight>
</source>
 
=== [[PHP]] ===
[[PHP]]'s built-in array type is, in reality, an associative array. Even when using numerical indexes, PHP internally stores itarrays as an associative arrayarrays.<ref>About the implementation of [http://se.php.net/manual/en/language.types.array.php Arrays] in PHP</ref> This is why one inSo, PHP can have non-consecutiveconsecutively numerically indexed arrays. The keys have to be of integer or string (floating point numbers are truncated to integer) or string type, while values can be of arbitrary types, including other arrays and objects. The arrays are heterogeneous;: a single array can have keys of different types. PHP's associative arrays can be used to represent trees, lists, stacks, queues, and other common data structures not built into PHP.
 
An associative array can be declared using the following syntax:
 
<sourcesyntaxhighlight lang=PHP"php">
$phonebook = array();
$phonebook['Sally Smart'] = '555-9999';
Line 1,278 ⟶ 1,406:
$phonebook['contacts']['John Doe']['number'] = '555-1212';
$phonebook['contacts']['J. Random Hacker']['number'] = '555-1337';
</syntaxhighlight>
</source>
 
PHP can loop through an associative array as follows:
 
<sourcesyntaxhighlight lang=PHP"php">
foreach ($phonebook as $name => $number) {
echo 'Number for ', $name, ': ', $number, "\n";
}
 
// For the last array example it is used like this
foreach ($phonebook['contacts'] as $name => $num) {
echo 'Name: ', $name, ', number: ', $num['number'], "\n";
}
</syntaxhighlight>
</source>
 
PHP has an [http://php.net/array extensive set of functions] to operate on arrays.<ref>{{cite web |title=Arrays |url=https://www.php.net/manual/en/language.types.array.php |website=PHP.net |access-date=3 August 2020}}</ref>
 
IfAssociative you want an associative arrayarrays that can use objects as keys, instead of strings and integers, you can usebe implemented with the [http://php.net<code>SplObjectStorage</SplObjectStorage SplObjectStorage]code> class from the Standard PHP Library (SPL).<ref>{{cite web |title=The SplObjectStorage class |url=http://php.net/SplObjectStorage |website=PHP.net |access-date=3 August 2020}}</ref>
 
=== [[Pike (programming language)|Pike]] ===
[[Pike (programming language)|Pike]] has built-in support for Associativeassociative Arraysarrays, which are referred to as mappings. Mappings are created as follows:
 
<sourcesyntaxhighlight lang=Pike"pike">
mapping(string:string) phonebook = ([
"Sally Smart":"555-9999",
Line 1,306 ⟶ 1,434:
"J. Random Hacker":"555-1337"
]);
</syntaxhighlight>
</source>
 
Accessing and testing for presence in mappings is done using the indexing operator. So <code>phonebook["Sally Smart"]</code> would return the string <code>"555-9999"</code>, and <code>phonebook["John Smith"]</code> would return 0.
 
Iterating through a mapping can be done using either <code>foreach</code>:
 
<sourcesyntaxhighlight lang="pike">
foreach(phonebook; string key; string value) {
write("%s:%s\n", key, value);
}
</syntaxhighlight>
</source>
 
Or using an iterator object:
 
<sourcesyntaxhighlight lang="pike">
Mapping.Iterator i = get_iterator(phonebook);
while (i->index()) {
Line 1,326 ⟶ 1,454:
i->next();
}
</syntaxhighlight>
</source>
 
Elements of a mapping can be removed using <code>m_delete</code>, which returns the value of the removed index:
 
<sourcesyntaxhighlight lang="pike">
string sallys_number = m_delete(phonebook, "Sally Smart");
</syntaxhighlight>
</source>
 
=== PostScript ===
In [[PostScript]], associative arrays are called dictionaries. In Level 1 PostScript they must be created explicitly, but Level 2 introduced direct declaration using thea double-braceangled-bracket syntax:
 
<sourcesyntaxhighlight lang="postscript">
% Level 1 declaration
3 dict dup begin
Line 1,353 ⟶ 1,481:
 
% Both methods leave the dictionary on the operand stack
</syntaxhighlight>
</source>
Dictionaries can be accessed directly using '''get''' or implicitly by placing the dictionary on the dictionary stack using '''begin''':
 
Dictionaries can be accessed directly, using <code>get</code>, or implicitly, by placing the dictionary on the dictionary stack using <code>begin</code>:
<source lang="postscript">
 
<syntaxhighlight lang="postscript">
% With the previous two dictionaries still on the operand stack
/red get print % outputs 'rot'
Line 1,363 ⟶ 1,492:
green print % outputs 'vert'
end
</syntaxhighlight>
</source>
 
Dictionary contents can be iterated through using '''<code>forall'''</code>, though not in any particular order:
 
<sourcesyntaxhighlight lang="postscript">
% Level 2 example
<<
Line 1,374 ⟶ 1,503:
/Other 3
>> {exch =print ( is ) print ==} forall
</syntaxhighlight>
</source>
 
May well output:
Which may output:
<source lang="postscript">
 
<syntaxhighlight lang="postscript">
That is 2
This is 1
Other is 3
</syntaxhighlight>
</source>
 
Dictionaries can be augmented (up to their defined size only in Level 1) or altered using '''<code>put'''</code>, and entries can be removed using '''<code>undef'''</code>:
<sourcesyntaxhighlight lang="postscript">
% define a dictionary for easy reuse:
/MyDict <<
Line 1,398 ⟶ 1,529:
% remove something
MyDict /rouge undef
</syntaxhighlight>
</source>
 
=== Prolog ===
 
Some versions of [[Prolog]] include dictionary ("dictsdict") utilities.<ref>[http://www.swi-prolog.org/pldoc/man?section=dicts "Dicts: structures with named arguments"]</ref>
[http://www.swi-prolog.org/pldoc/man?section=dicts "Dicts: structures with named arguments"].
</ref>
 
=== [[Python (programming language)|Python]] ===
In [[Python (programming language)|Python]], associative arrays are called ''"[[Python syntax and semantics#Collection types|dictionaries]]''". Dictionary literals are markeddelimited withby curly braces:
 
<sourcesyntaxhighlight lang=Python"python">
phonebook = {
'"Sally Smart'": '"555-9999'",
'"John Doe'": '"555-1212'",
'"J. Random Hacker'": '"553-1337'",
}
</syntaxhighlight>
</source>
 
ToDictionary accessitems ancan entrybe inaccessed Python simply useusing the array indexing operator. For example,:
<sourcesyntaxhighlight lang=Pycon"python">
>>> phonebook['"Sally Smart'"]
'555-9999'
</syntaxhighlight>
</source>
 
An example loop [[iterator#Python|iterating]] through all the keys of the dictionary:
Loop [[iterator#Python|iterating]] through all the keys of the dictionary:
 
<sourcesyntaxhighlight lang=Pycon"python">
>>> for key in phonebook:
... print(key, phonebook[key])
Line 1,430 ⟶ 1,560:
J. Random Hacker 553-1337
John Doe 555-1212
</syntaxhighlight>
</source>
 
Iterating through (key, value) tuples:
 
<sourcesyntaxhighlight lang=Pycon"python">
>>> for key, value in phonebook.items():
... print(key, value)
Line 1,440 ⟶ 1,570:
J. Random Hacker 553-1337
John Doe 555-1212
</syntaxhighlight>
</source>
 
Dictionary keys can be individually deleted using the <code>del</code> statement. The corresponding value can be returned before the key-value pair areis deleted using the "pop" method of "dict" typestype:
 
<sourcesyntaxhighlight lang=Pycon"python">
>>> del phonebook['"John Doe'"]
>>> val = phonebook.pop('"Sally Smart'")
>>> phonebook.keys() # Only one key left
['J. Random Hacker']
</syntaxhighlight>
</source>
 
Python 2.7 and 3.x also support [https://peps.python.org/pep-0274/ dict comprehensions] (similar to [[list comprehension]]s), a compact syntax for generating a dictionary from any iterator:
 
<syntaxhighlight lang="python">
Python 2.7 and 3.x also supports dictionary comprehensions, a compact syntax for generating a dictionary from any iterator:
<source lang=Pycon>
>>> square_dict = {i: i*i for i in range(5)}
>>> square_dict
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
>>> {key: value for key, value in phonebook.items() if '"J'" in key}
{'J. Random Hacker': '553-1337', 'John Doe': '555-1212'}
</syntaxhighlight>
</source>
 
Strictly speaking, a dictionary is a super-set of an associative array, since neither the keys or values are limited to a single datatype. One could think of a dictionary as an ''"associative list''" using the nomenclature of Python. For example, the following is also legitimate:
 
<sourcesyntaxhighlight lang=Python"python">
phonebook = {
'"Sally Smart'": '"555-9999'",
'"John Doe'": None,
'"J. Random Hacker'": -3.32,
14: '"555-3322'",
}
</syntaxhighlight>
</source>
 
The dictionary keys must be of an [[Immutable object|immutable]] data type. In Python, strings are immutable due to their method of implementation.
 
=== [[Red (programming language)|Red]] ===
In [[Red (programming language)|Red]] the built-in <code>map!</code><ref>{{cite web|url=https://doc.red-lang.org/en/datatypes/map.html|title=Map! datatype|website=doc.red-lang.org}}</ref> datatype provides an associative array mappingthat maps values of word, string, and scalar key types to values of any type. A hash table is used internally for lookup of keys.
 
A map can be written as a literal, such as <code>#(key1 value1 key2 value2 ...)</code>, or can be created using <code>make map! [key1 value1 key2 value2 ...]</code>:
 
<syntaxhighlight lang="red">
A map can be written as a literal like <code>#(key1 value1 key2 value2 ...)</code>, or can be created using <code>make map! [key1 value1 key2 value2 ...]</code>. For example:
Red [Title:"My map"]
 
<source lang=Red>
my-map: make map! [
"Sally Smart" "555-9999"
Line 1,484 ⟶ 1,617:
"J. Random Hacker" "553-1337"
]
</source>
 
; Red preserves case for both keys and values, however lookups are case insensitive by default; it is possible to force case sensitivity using the <code>/case</code> refinement for <code>select</code> and <code>put</code>.
 
; It is of course possible to use <code>word!</code> values as keys, in which case it is generally preferred to use <code>set-word!</code> values when creating the map, but any word type can be used for lookup or creation.
 
<source lang=Red>
my-other-map: make map! [foo: 42 bar: false]
</source>
 
; Notice that the block is not reduced or evaluated in any way, therefore in the above example the key <code>bar</code> is associated with the <code>word!</code> <code>false</code> rather than the <code>logic!</code> value false; literal syntax can be used if the latter is desired:
 
<source lang=Red>
my-other-map: make map! [foo: 42 bar: #[false]]
</source>
 
; or keys can be added after creation:
 
<source lang=Red>
my-other-map: make map! [foo: 42]
my-other-map/bar: false
</source>
 
; Lookup can be written using <code>path!</code> notation or using the <code>select</code> action:
 
<source lang=Red>
select my-map "Sally Smart"
my-other-map/foo
</source>
 
; You can also loop through all keys and values with <code>foreach</code>:
 
<source lang=Red>
foreach [key value] my-map [
print [key "is associated to" value]
]
</source>
 
; A key can be removed using <code>remove/key</code>:
 
<source lang=Red>
remove/key my-map "Sally Smart"
</syntaxhighlight>
</source>
 
=== [[REXX]] ===
In [[REXX]], associative arrays are called ''Stem"stem variables''" or ''"Compound variables''".
 
<sourcesyntaxhighlight lang=REXX"rexx">
KEY = 'Sally Smart'
PHONEBOOK.KEY = '555-9999'
Line 1,538 ⟶ 1,659:
KEY = 'J. Random Hacker'
PHONEBOOK.KEY = '553-1337'
</syntaxhighlight>
</source>
 
Stem variables with numeric keys typically start at 1 and go up from there. The 0 -key stem variable
is used (by convention) ascontains the counttotal number of items in the whole stem.:
 
<sourcesyntaxhighlight lang=REXX"rexx">
NAME.1 = 'Sally Smart'
NAME.2 = 'John Doe'
NAME.3 = 'J. Random Hacker'
NAME.0 = 3
</syntaxhighlight>
</source>
 
REXX has no easy way of automatically accessing the keys forof a stem variable; and typically the
keys are stored in a separate associative array, with numeric keys.
 
=== [[Ruby programming language|Ruby]] ===
In [[Ruby programming language|Ruby]] a hash table is used as follows:
 
<syntaxhighlight lang="rb">
In Ruby a [[hash table|hash]] is used as follows:
phonebook = {
 
'Sally Smart' => '555-9999',
<source lang=irb>
'John Doe' => '555-1212',
irb(main):001:0> phonebook = {
irb(main):002:1* 'SallyJ. Random SmartHacker' => '555553-99991337',
}
irb(main):003:1* 'John Doe' => '555-1212',
phonebook['John Doe']
irb(main):004:1* 'J. Random Hacker' => '553-1337'
</syntaxhighlight>
irb(main):005:1> }
=> {"Sally Smart"=>"555-9999", "John Doe"=>"555-1212", "J. Random Hacker"=>"553-1337"}
irb(main):006:0> phonebook['John Doe']
=> "555-1212"
</source>
 
Ruby supports hash looping and iteration with the following syntax:
 
<sourcesyntaxhighlight lang="irb">
irb(main):007:0> ### iterate over keys and values
irb(main):008:0* phonebook.each {|key, value| puts key + " => " + value}
Line 1,589 ⟶ 1,707:
553-1337
=> {"Sally Smart"=>"555-9999", "John Doe"=>"555-1212", "J. Random Hacker"=>"553-1337"}
</syntaxhighlight>
</source>
 
Ruby also supports many other useful operations on hashes, such as merging hashes, selecting or rejecting elements that meet some criteria, inverting (swapping the keys and values), and flattening a hash into an array.
 
===Rust===
=== [[S-Lang (programming language)|S-Lang]] ===
The [[Rust (programming language)|Rust]] standard library provides a hash map (<code>std::collections::HashMap</code>) and a [[B-tree]] map (<code>std::collections::BTreeMap</code>). They share several methods with the same names, but have different requirements for the types of keys that can be inserted. The <code>HashMap</code> requires keys to implement the <code>Eq</code> ([[equivalence relation]]) and <code>Hash</code> (hashability) traits and it stores entries in an unspecified order, and the <code>BTreeMap</code> requires the <code>Ord</code> ([[total order]]) trait for its keys and it stores entries in an order defined by the key type. The order is reflected by the default iterators.
S-Lang has an associative array type.
 
<syntaxhighlight lang="rust">
For example:
use std::collections::HashMap;
let mut phone_book = HashMap::new();
phone_book.insert("Sally Smart", "555-9999");
phone_book.insert("John Doe", "555-1212");
phone_book.insert("J. Random Hacker", "555-1337");
</syntaxhighlight>
 
The default iterators visit all entries as tuples. The <code>HashMap</code> iterators visit entries in an unspecified order and the <code>BTreeMap</code> iterator visits entries in the order defined by the key type.
<syntaxhighlight lang="rust">
for (name, number) in &phone_book {
println!("{} {}", name, number);
}
</syntaxhighlight>
 
There is also an iterator for keys:
<syntaxhighlight lang="rust">
for name in phone_book.keys() {
println!("{}", name);
}
</syntaxhighlight>
 
===S-Lang===
[[S-Lang]] has an associative array type:
 
<sourcesyntaxhighlight lang="text">
phonebook = Assoc_Type[];
phonebook["Sally Smart"] = "555-9999"
phonebook["John Doe"] = "555-1212"
phonebook["J. Random Hacker"] = "555-1337"
</syntaxhighlight>
</source>
 
You can also loop through an associated array in a number of ways.:
Here is one
 
<sourcesyntaxhighlight lang="text">
foreach name (phonebook) {
vmessage ("%s %s", name, phonebook[name]);
}
</syntaxhighlight>
</source>
 
To print a sorted-list, it is better to take advantage of S-lang's strong
support for standard arrays:
 
<sourcesyntaxhighlight lang="text">
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]);
</syntaxhighlight>
</source>
 
=== [[Scala (programming language)|Scala]] ===
[[Scala (programming language)|Scala]] provides an immutable <code>Map</code> class as part of the <code>scala.collection</code> framework:
 
<sourcesyntaxhighlight lang=Scala"scala">
val phonebook = Map("Sally Smart" -> "555-9999",
"John Doe" -> "555-1212",
"J. Random Hacker" -> "553-1337")
</syntaxhighlight>
</source>
 
Scala's [[type inference]] will work outdecide that this is a <code>Map[String, String]</code>. To access the array:
 
<sourcesyntaxhighlight lang=Scala"scala">
phonebook.get("Sally Smart")
</syntaxhighlight>
</source>
 
This returns an <code>Option</code> type, Scala's equivalent of athe [[Monad (functional programming)#The Maybe monad|the Maybe monad]] in Haskell.
 
=== [[Smalltalk]] ===
In [[Smalltalk]] a dictionary<code>Dictionary</code> is used:
 
<sourcesyntaxhighlight lang=Smalltalk"smalltalk">
phonebook := Dictionary new.
phonebook at: 'Sally Smart' put: '555-9999'.
phonebook at: 'John Doe' put: '555-1212'.
phonebook at: 'J. Random Hacker' put: '553-1337'.
</syntaxhighlight>
</source>
 
To access an entry the message <code>#at:</code> is sent to the dictionary object.:
 
<sourcesyntaxhighlight lang=Smalltalk"smalltalk">
phonebook at: 'Sally Smart'
</syntaxhighlight>
</source>
 
Which gives:
 
<sourcesyntaxhighlight lang=Text"text">
'555-9999'
</syntaxhighlight>
</source>
 
Dictionary hashes/compares based on equality and holds
A dictionary hashes, or compares, based on equality and marks both key and value as
[[Garbage collection (computer science)#Strong and weak references|strong references]] to both key and value. Variants exist which hash/compare on identity (IdentityDictionary) or keep [[Garbage collection (computer science)#Strong and weak references|weak references]] (WeakKeyDictionary / WeakValueDictionary).
[[Garbage collection (computer science)#Strong and weak references|strong references]]. Variants exist in which hash/compare on identity (IdentityDictionary) or keep [[Garbage collection (computer science)#Strong and weak references|weak references]] (WeakKeyDictionary / WeakValueDictionary).
Because every object implements #hash, any object can be used as key (and of course also as value).
 
=== [[SNOBOL]] ===
[[SNOBOL]] is one of the first (if not the first) programming languages to use associative arrays. Associative arrays in SNOBOL are called Tables.
Associative arrays in [[SNOBOL]] are called Tables.
 
<sourcesyntaxhighlight lang="snobol">
PHONEBOOK = TABLE()
PHONEBOOK['Sally Smart'] = '555-9999'
PHONEBOOK['John Doe'] = '555-1212'
PHONEBOOK['J. Random Hacker'] = '553-1337'
</syntaxhighlight>
</source>
 
=== [[Standard ML]] ===
The SML'97 standard of the [[Standard ML]] programming language does not provide any associative containers. However, various implementations of Standard ML do provide associative containers.
 
The library of the popular [[Standard ML of New Jersey]] (SML/NJ) implementation provides a signature (somewhat like an "interface"), <code>ORD_MAP</code>, which defines a common interface for ordered functional (immutable) associative arrays. There are several general functors, functors—<code>BinaryMapFn</code>, <code>ListMapFn</code>, <code>RedBlackMapFn</code>, and <code>SplayMapFn</code>, that—that allow you to create the corresponding type of ordered map (the types are a [[self-balancing binary search tree]], sorted [[association list]], [[red-blackred–black tree]], and [[splay tree]], respectively) using a user-provided structure to describe the key type and comparator. The functor returns a structure thatin followsaccordance with the <code>ORD_MAP</code> interface. In addition, there are two pre-defined modules for associative arrays withthat employ integer keys: <code>IntBinaryMap</code> and <code>IntListMap</code>.
 
<sourcesyntaxhighlight lang="sml">
- structure StringMap = BinaryMapFn (struct
type ord_key = string
Line 1,700 ⟶ 1,840:
- StringMap.find (m, "John Doe");
val it = SOME "555-1212" : string option
</syntaxhighlight>
</source>
 
SML/NJ also provides a polymorphic hash table:
 
<sourcesyntaxhighlight lang="sml">
- exception NotFound;
exception NotFound
Line 1,723 ⟶ 1,863:
- HashTable.lookup m "John Doe"; (* raises the exception if not found *)
val it = "555-1212" : string
</syntaxhighlight>
</source>
 
Monomorphic hash tables are also supported, using the <code>HashTableFn</code> functor.
 
Another Standard ML implementation, [[Moscow ML]], also provides some associative containers. First, it provides polymorphic hash tables in the <code>Polyhash</code> structure. Also, some functional maps from the SML/NJ library above are available as <code>Binarymap</code>, <code>Splaymap</code>, and <code>Intmap</code> structures.
 
=== [[Tcl]] ===
There are two [[Tcl]] facilities that support associative -array semantics. An "array" is a collection of ''variables''. A '''"dict'''" is a full implementation of associative arrays.
 
====dict====
 
<source lang=Tcl>
set phonebook [dict create {Sally Smart} 555-9999 {John Doe} 555-1212 {J. Random Hacker} 553-1337]
</source>
 
To look up an item:
 
<source lang=Tcl>
dict get $phonebook {John Doe}
</source>
 
To iterate through a dict:
 
<source lang=Tcl>
foreach {name number} $phonebook {
puts "name: $name\nnumber: $number"
}
</source>
 
====array====
<syntaxhighlight lang=Tcl>
 
<source lang=Tcl>
set {phonebook(Sally Smart)} 555-9999
set john {John Doe}
set phonebook($john) 555-1212
set {phonebook(J. Random Hacker)} 553-1337
</syntaxhighlight>
</source>
 
If there is a literal space character in the variable name, itthe name must be grouped using either curly brackets (no substitution performed) or double quotes (substitution is performed).
 
Alternatively, several array elements can be set inby a single command, by providingpresenting their mappings as a list (words containing whitespace are braced):
 
<sourcesyntaxhighlight lang=Tcl>
array set phonebook [list {Sally Smart} 555-9999 {John Doe} 555-1212 {J. Random Hacker} 553-1337]
</syntaxhighlight>
</source>
 
To access one array entry and put it onto standard output:
 
<sourcesyntaxhighlight lang=Tcl>
puts $phonebook(Sally\ Smart)
</syntaxhighlight>
</source>
 
Which returns this result:
The result is here
 
<sourcesyntaxhighlight lang=Text>
555-9999
</syntaxhighlight>
</source>
 
To retrieve the entire array as a dictionary:
 
<sourcesyntaxhighlight lang=Tcl>
array get phonebook
</syntaxhighlight>
</source>
 
The result can be (order of keys is unspecified, not because the dictionary is unordered, but because the array is):
 
<sourcesyntaxhighlight lang=Tcl>
{Sally Smart} 555-9999 {J. Random Hacker} 553-1337 {John Doe} 555-1212
</syntaxhighlight>
</source>
 
=== [[Visual Basic]] =dict====
<syntaxhighlight lang=Tcl>
There is no standard implementation common to all dialects. Visual Basic can use the Dictionary class from the [[Windows Scripting Host|Microsoft Scripting Runtime]] (which is shipped with Visual Basic 6):
set phonebook [dict create {Sally Smart} 555-9999 {John Doe} 555-1212 {J. Random Hacker} 553-1337]
</syntaxhighlight>
 
To look up an item:
<source lang=VB>
 
<syntaxhighlight lang=Tcl>
dict get $phonebook {John Doe}
</syntaxhighlight>
 
To iterate through a dict:
 
<syntaxhighlight lang=Tcl>
foreach {name number} $phonebook {
puts "name: $name\nnumber: $number"
}
</syntaxhighlight>
 
=== Visual Basic ===
[[Visual Basic]] can use the Dictionary class from the [[Windows Scripting Host|Microsoft Scripting Runtime]] (which is shipped with Visual Basic 6). There is no standard implementation common to all versions:
 
<syntaxhighlight lang="vbnet">
' Requires a reference to SCRRUN.DLL in Project Properties
Dim phoneBook As New Dictionary
Line 1,805 ⟶ 1,943:
MsgBox name & " = " & phoneBook(name)
Next
</syntaxhighlight>
</source>
 
=== [[Visual Basic .NET]] ===
[[Visual Basic .NET]] uses the collection classes provided by the [[.NET Framework]].
 
====Creation====
The following code demonstrates the creation and population of a dictionary (see [[#C#|the C# example on this page]] for additional information):
 
<syntaxhighlight lang=VBNet>
The following code demonstrates the creation and population of a dictionary. See [[#C#|the C# example on this page]] for additional information.
<source lang=VBNet>
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"
</syntaxhighlight>
</source>
 
An alternativealternate syntax would be to use a ''collection initializer'', which compiles down to individual calls to <code>Add</code>.:
 
<source lang=VBNet>
<syntaxhighlight lang=VBNet>
Dim dic As New System.Collections.Dictionary(Of String, String) From {
{"Sally Smart", "555-9999"},
Line 1,827 ⟶ 1,966:
{"J. Random Hacker", "553-1337"}
}
</syntaxhighlight>
</source>
 
====Access by key====
Example demonstrating access (see [[#C# access|C# access]]):
 
<syntaxhighlight lang=VBNet>
Example demonstrating access; see [[#C# access|this section of the C# example]] for explanation:
<source lang=VBNet>
Dim sallyNumber = dic("Sally Smart")
' or
Dim sallyNumber = dic.Item("Sally Smart")
</syntaxhighlight>
</source>
<sourcesyntaxhighlight lang=VBNet>
Dim result As String = Nothing
Dim sallyNumber = If(dic.TryGetValue("Sally Smart", result), result, "n/a")
</syntaxhighlight>
</source>
 
====Enumeration====
Example demonstrating enumeration (see [[#C# enumeration]]):
 
<syntaxhighlight lang=VBNet>
Example demonstrating enumeration; see [[#C# enumeration|this section of the C# example]] for explanation:
<source lang=VBNet>
' loop through the collection and display each entry.
For Each kvp As KeyValuePair(Of String, String) In dic
Console.WriteLine("Phone number for {0} is {1}", kvp.Key, kvp.Value)
Next
</syntaxhighlight>
</source>
 
=== [[Windows PowerShell]] ===
Unlike many other [[command line interpreter]]s, [[Windows PowerShell]] has built-in, language-level support for defining associative arrays.:
 
<syntaxhighlight lang=PowerShell>
For example:
 
<source lang=PowerShell>
$phonebook = @{
'Sally Smart' = '555-9999';
Line 1,863 ⟶ 2,000:
'J. Random Hacker' = '553-1337'
}
</syntaxhighlight>
</source>
 
LikeAs in JavaScript, if the property name is a valid identifier, the quotes can be omitted, e.g.:
 
<sourcesyntaxhighlight lang=PowerShell>
$myOtherObject = @{ foo = 42; bar = $false }
</syntaxhighlight>
</source>
 
Entries can be separated by either a semicolon or a newline, e.g.:
 
<sourcesyntaxhighlight lang=PowerShell>
$myOtherObject = @{ foo = 42
bar = $false ;
zaz = 3
}
</syntaxhighlight>
</source>
 
Keys and values can be any [[.NET Framework|.NET]] object type, e.g.:
 
<sourcesyntaxhighlight lang=PowerShell>
$now = [DateTime]::Now
$tomorrow = $now.AddDays(1)
Line 1,889 ⟶ 2,026:
(Get-Process calc) = $tomorrow
}
</syntaxhighlight>
</source>
 
It is also possible to create an empty associative array and add single entries, or even other associative arrays, to it later on.:
 
<sourcesyntaxhighlight lang=PowerShell>
$phonebook = @{}
$phonebook += @{ 'Sally Smart' = '555-9999' }
$phonebook += @{ 'John Doe' = '555-1212'; 'J. Random Hacker' = '553-1337' }
</syntaxhighlight>
</source>
 
New entries can also be added by using the array index operator, the property operator, or the <code>Add()</code> method of the underlying .NET object:
 
<sourcesyntaxhighlight lang=PowerShell>
$phonebook = @{}
$phonebook['Sally Smart'] = '555-9999'
$phonebook.'John Doe' = '555-1212'
$phonebook.Add('J. Random Hacker', '553-1337')
</syntaxhighlight>
</source>
 
To dereference assigned objects, the array index operator, the property operator, or the parameterized property <code>Item()</code> of the .NET object can be used:
 
<sourcesyntaxhighlight lang=PowerShell>
$phonebook['Sally Smart']
$phonebook.'John Doe'
$phonebook.Item('J. Random Hacker')
</syntaxhighlight>
</source>
 
You can loop through an associative array as follows:
 
<sourcesyntaxhighlight lang=PowerShell>
$phonebook.Keys | foreach { "Number for {0}: {1}" -f $_,$phonebook.$_ }
</syntaxhighlight>
</source>
 
An entry can be removed using the <code>Remove()</code> method of the underlying .NET object:
 
<sourcesyntaxhighlight lang=PowerShell>
$phonebook.Remove('Sally Smart')
</syntaxhighlight>
</source>
 
Hash tables can be added, e.g.:
 
<sourcesyntaxhighlight lang=PowerShell>
$hash1 = @{ a=1; b=2 }
$hash2 = @{ c=3; d=4 }
$hash3 = $hash1 + $hash2
</syntaxhighlight>
</source>
 
==Data serialization formats support==
Line 1,941 ⟶ 2,078:
Many data serialization formats also support associative arrays (see [[Comparison of data serialization formats#Syntax comparison of human-readable formats|this table]])
 
=== [[JSON]] ===
In [[JSON]], associative arrays are also referred to as objects. Keys can only be strings.
 
<source lang=JavaScript>
<syntaxhighlight lang=JavaScript>
{
"Sally Smart": "555-9999",
Line 1,949 ⟶ 2,087:
"J. Random Hacker": "555-1337"
}
</syntaxhighlight>
</source>
 
=== TOML ===
[[TOML]] is designed to map directly to a hash map. TOML refers to associative arrays as tables. Tables within TOML can be expressed in either an "unfolded" or an inline approach. Keys can only be strings.<syntaxhighlight lang="toml">[phonebook]
"Sally Smart" = "555-9999"
"John Doe" = "555-1212"
"J. Random Hacker" = "555-1337"</syntaxhighlight><syntaxhighlight lang="toml">
phonebook = { "Sally Smart" = "555-9999", "John Doe" = "555-1212", "J. Random Hacker" = "555-1337" }
 
</syntaxhighlight>
=== [[YAML]] ===
 
===YAML===
YAML associative arrays are also called map elements or key-value pairs. YAML places no restrictions on the type of keys; in particular, they are not restricted to being scalar or string values.
[[YAML]] associative arrays are also called map elements or key-value pairs. YAML places no restrictions on the types of keys; in particular, they are not restricted to being scalar or string values.
 
<sourcesyntaxhighlight lang=YAML>
Sally Smart: 555-9999
John Doe: 555-1212
J. Random Hacker: 555-1337
</syntaxhighlight>
</source>
 
== References ==
Line 1,966 ⟶ 2,112:
[[Category:Associative arrays|Programming language comparison]]
[[Category:Programming language comparisons|*Mapping]]
[[Category:Articles with example Julia code]]