Content deleted Content added
m Task 70: Update syntaxhighlight tags - remove use of deprecated <source> tags |
|||
Line 13:
For example:
<
phonebook["Sally Smart"] = "555-9999"
phonebook["John Doe"] = "555-1212"
phonebook["J. Random Hacker"] = "555-1337"
</syntaxhighlight>
You can also loop through an associated array as follows:
<
for (name in phonebook) {
print name, " ", phonebook[name]
}
</syntaxhighlight>
You can also check if an element is in the associative array, and delete elements from an associative array.
Line 31:
Multi-dimensional associative arrays can be simulated in standard Awk using concatenation and e.g. SUBSEP:
<
{ # for every input line
multi[$1 SUBSEP $2]++;
Line 42:
}
}
</syntaxhighlight>
=== [[C (programming language)|C]] ===
Line 63:
* assigning to the indexer, which overwrites any existing value, if present, and
* (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.
<
Dictionary<string, string> dic = new Dictionary<string, string>();
dic.Add("Sally Smart", "555-9999");
Line 70:
// dic.Item("J. Random Hacker") = "553-1337";
dic["J. Random Hacker"] = "553-1337";
</syntaxhighlight>
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 dic = new Dictionary<string, string> {
{ "Sally Smart", "555-9999" },
Line 79:
{ "J. Random Hacker", "553-1337" }
};
</syntaxhighlight>
===={{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.
<
var sallyNumber = dic["Sally Smart"];
</syntaxhighlight>
<
var sallyNumber = (dic.TryGetValue("Sally Smart", out var result) ? result : "n/a";
</syntaxhighlight>
In this example, the <code>sallyNumber</code> value will now contain the string <code>"555-9999"</code>.
Line 97:
The following demonstrates enumeration using a [[foreach loop]]:
<
// loop through the collection and display each entry.
foreach(KeyValuePair<string,string> kvp in dic)
Line 103:
Console.WriteLine("Phone number for {0} is {1}", kvp.Key, kvp.Value);
}
</syntaxhighlight>
=== [[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 map with the same information as above using C++ with the following code:
<
#include <map>
#include <string>
Line 119:
phone_book.insert(std::make_pair("J. Random Hacker", "553-1337"));
}
</syntaxhighlight>
Or less efficiently as it creates temporary <code>std::string</code> values:
<
#include <map>
#include <string>
Line 132:
phone_book["J. Random Hacker"] = "553-1337";
}
</syntaxhighlight>
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:
<
#include <map>
#include <string>
Line 147:
};
}
</syntaxhighlight>
You can iterate through the list with the following code (C++03):
<
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>
The same task in new C++11:
<
for(const auto& curr : phone_book)
std::cout << curr.first << " = " << curr.second << std::endl;
</syntaxhighlight>
Using the structured binding available in [[C++17]]:
<
for (const auto& [name, number] : phone_book) {
std::cout << name << " = " << number << std::endl;
}
</syntaxhighlight>
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> with the algorithmic characteristics of a hash table. This is a common vendor extension to the STL as well, usually called <code>hash_map</code>, being available from such implementations as SGI and STLPort.
Line 177:
A structure in CFML is equivalent to an associative array:
<
dynamicKeyName = "John Doe";
phoneBook = {
Line 187:
writeOutput(phoneBook.UnknownComic); // ???
writeDump(phoneBook); // entire struct
</syntaxhighlight>
=== [[Cobra (programming language)|Cobra]] ===
Line 216:
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:
<
int main() {
string[ string ] phone_book;
Line 224:
return 0;
}
</syntaxhighlight>
Keys and values can be any types, but all the keys in an associative array
Line 231:
You can also loop through all properties and associated values, i.e. as follows:
<
foreach (key, value; phone_book) {
writeln("Number for " ~ key ~ ": " ~ value );
}
</syntaxhighlight>
A property can be removed as follows:
<
phone_book.remove("Sally Smart");
</syntaxhighlight>
=== [[Borland Delphi|Delphi]] ===
Delphi supports several standard generic containers, including TDictionary<T>:
<
uses
SysUtils,
Line 263:
Writeln(Format('Number for %s: %s',[Entry.Key, Entry.Value]));
end.
</syntaxhighlight>
Versions of Delphi prior to 2009 do not offer direct support for associative arrays. However, you can simulate associative arrays using the TStrings class. Here's an example:
<
procedure TForm1.Button1Click(Sender: TObject);
var
Line 290:
DataField.Free;
end;
</syntaxhighlight>
=== [[Erlang (programming language)|Erlang]] ===
Line 297:
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.
<
PhoneBook = [{"Sally Smart", "555-9999"},
{"John Doe", "555-1212"},
{"J. Random Hacker", "553-1337"}].
</syntaxhighlight>
Accessing an element of the keylist can be done with the <code>lists:keyfind/3</code> function:
<
{_, Phone} = lists:keyfind("Sally Smart", 1, PhoneBook),
io:format("Phone number: ~s~n", [Phone]).
</syntaxhighlight>
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:
<
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>
Such a serial initialization would be more idiomatically represented in Erlang with the appropriate function:
<
PhoneBook = dict:from_list([{"Sally Smith", "555-9999"}, {"John Doe", "555-1212"},
{"J. Random Hacker", "553-1337"}]).
</syntaxhighlight>
The dictionary can be accessed using the <code>dict:find/2</code> function:
<
{ok, Phone} = dict:find("Sally Smith", PhoneBook),
io:format("Phone: ~s~n", [Phone]).
</syntaxhighlight>
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.
Line 344:
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).
<
let numbers =
[
Line 351:
"J. Random Hacker", "555-1337"
] |> Map
</syntaxhighlight>
=====''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></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.
<
let sallyNumber = numbers.["Sally Smart"]
// or
let sallyNumber = numbers.Item("Sally Smart")
</syntaxhighlight>
<
let sallyNumber =
match numbers.TryFind("Sally Smart") with
| Some(number) -> number
| None -> "n/a"
</syntaxhighlight>
In both examples above, the <code>sallyNumber</code> value would contain the string <code>"555-9999"</code>.
Line 376:
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>.
<
let numbers =
[
Line 383:
"J. Random Hacker", "555-1337"
] |> dict
</syntaxhighlight>
When a mutable dictionary is needed, the constructor of <code>System.Collections.Generic.Dictionary<'TKey,'TValue></code> can be called directly. See [[#C#|the C# example on this page]] for additional information.
<
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>
=====''Access by key''=====
<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.
<
let sallyNumber =
let mutable result = ""
if numbers.TryGetValue("Sally Smart", &result) then result else "n/a"
</syntaxhighlight>
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:
<
let sallyNumber =
match numbers.TryGetValue("Sally Smart") with
| true, number -> number
| _ -> "n/a"
</syntaxhighlight>
====Enumeration====
A dictionary or map can be enumerated using <code>Seq.map</code>.
<
// 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>
=== [[FoxPro]] ===
[[Visual FoxPro]] implements mapping with the Collection Class.
<
mapping = NEWOBJECT("Collection")
mapping.Add("Daffodils", "flower2") && Add(object, key) – key must be character
Line 427:
object = mapping("flower2") && returns "Daffodils" (retrieve by key)
object = mapping(1) && returns "Daffodils" (retrieve by index)
</syntaxhighlight>
GetKey returns 0 if the key is not found.
Line 437:
Adding elements one at a time:
<
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>
A map literal:
<
phone_book := map[string] string {
"Sally Smart": "555-9999",
Line 451:
"J. Random Hacker": "553-1337",
}
</syntaxhighlight>
Iterating over a map:
<
// over both keys and values
for key, value := range phone_book {
Line 464:
fmt.Printf("Name: %s\n", key)
}
</syntaxhighlight>
=== [[Haskell (programming language)|Haskell]] ===
The Haskell programming language's report only provides one kind of associative container: a list of pairs:
<
m = [("Sally Smart", "555-9999"), ("John Doe", "555-1212"), ("J. Random Hacker", "553-1337")]
main = print (lookup "John Doe" m)
</syntaxhighlight>
output:
Just "555-1212"
Line 483:
One is polymorphic functional maps (represented as immutable balanced binary trees):
<
import qualified Data.Map as M
Line 491:
main = print (M.lookup "John Doe" m'' :: Maybe String)
</syntaxhighlight>
output:
Just "555-1212"
Line 499:
Finally, a polymorphic hash table:
<
import qualified Data.HashTable as H
Line 508:
foo <- H.lookup m "John Doe"
print foo
</syntaxhighlight>
output:
Just "555-1212"
Line 517:
In Java associative arrays are implemented as "maps"; they 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 mapping strings to strings might be specified as follows:
<
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>
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>.
Line 533:
For two objects ''a'' and ''b'',
<
a.equals(b) == b.equals(a)
if a.equals(b), then a.hashCode() == b.hashCode()
</syntaxhighlight>
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>.
Line 556:
A map can be initialized with all items during construction:
<
var phoneBook = new Map([
["Sally Smart", "555-9999"],
Line 562:
["J. Random Hacker", "553-1337"]
]);
</syntaxhighlight>
Alternatively, you can initialize an empty map and then add items:
<
var 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''=====
Line 577:
Accessing an element of the map can be done with the get method:
<
var sallyNumber = phoneBook.get("Sally Smart");
</syntaxhighlight>
In this example, the sallyNumber value will now contain the string "555-9999".
Line 587:
The keys in a map are ordered. Thus, when iterating over it, a map object returns keys in order of insertion. The following demonstrates enumeration using a for-loop:
<
// 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:
<
phoneBook.delete("Sally Smart");
</syntaxhighlight>
====Object====
Line 608:
An object literal is written as <code>{ property1 : value1, property2 : value2, ... }</code>. For example:
<
var myObject = {
"Sally Smart" : "555-9999",
Line 614:
"J. Random Hacker" : "553-1337"
};
</syntaxhighlight>
To prevent the lookup to the prototype, you can use Object.setPrototypeOf function:
<
Object.setPrototypeOf(myObject, null);
</syntaxhighlight>
As of ES5, this can also be bypassed by using Object.create(null):
<
var myObject = Object.create(null);
Line 631:
"J. Random Hacker" : "553-1337"
});
</syntaxhighlight>
If the property name is a valid identifier, the quotes can be omitted, e.g.:
<
var myOtherObject = { foo : 42, bar : false }
</syntaxhighlight>
Lookup is written using property access notation, either square brackets, which always works, or dot notation, which only works for identifier keys:
<
myObject["John Doe"]
myOtherObject.foo
</syntaxhighlight>
You can also loop through all enumerable properties and associated values as follows (a for-in loop):
<
for(var property in myObject) {
var value = myObject[property];
console.log("myObject[" + property + "] = " + value);
}
</syntaxhighlight>
Or (a for-of loop):
<
for(const [property, value] of Object.entries(myObject)) {
console.log(`${property} = ${value}`);
}
</syntaxhighlight>
A property can be removed as follows:
<
delete myObject["Sally Smart"];
</syntaxhighlight>
As mentioned before, properties are strings and symbols. Since every native object and primitive can be implicitly converted to a string, you can do:
<
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>
In modern JavaScript it's considered bad form to use the Array type as an associative array. Consensus is that the Object type and Map/WeakMap classes are 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.
Line 684:
Declare dictionary:
<
phonebook = Dict( "Sally Smart" => "555-9999", "John Doe" => "555-1212", "J. Random Hacker" => "555-1337" )
</syntaxhighlight>
Access element:
Line 708:
Definition:
<
typeset -A phonebook; # ksh93
declare -A phonebook; # bash4
phonebook=(["Sally Smart"]="555-9999" ["John Doe"]="555-1212" ["[[J. Random Hacker]]"]="555-1337");
</syntaxhighlight>
Dereference:
<
${phonebook["John Doe"]};
</syntaxhighlight>
=== [[Lisp programming language|Lisp]] ===
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").
<
'(("Sally Smart" . "555-9999")
("John Doe" . "555-1212")
("J. Random Hacker" . "553-1337"))
</syntaxhighlight>
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 provide operators such as <code>assoc</code> to manipulate alists in ways similar to associative arrays.
Line 733:
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.
<
(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>
This function can actually be construed as a convenience accommodating for <code>cons</code> operations.[https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node153.html]
<
;; The effect of
;; (cons (cons KEY VALUE) ALIST)
Line 749:
(let ((phone-book '(("Sally Smart" . "555-9999") ("John Doe" . "555-1212"))))
(cons (cons "J. Random Hacker" "555-1337") phone-book))
</syntaxhighlight>
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.
<
(push (cons "Dummy" "123-4567") phone-book)
</syntaxhighlight>
Searching for an entry by its key is performed via <code>assoc</code>, which might be configured regarding the test predicate and direction, especially searching from the association list end to its front. The result, if positive, constitutes the entire entry cons, not only its value. Failure to obtain a matching key leds to a return of the <code>NIL</code> value.
<
(assoc "John Doe" phone-book :test #'string=)
</syntaxhighlight>
Two generalizations of <code>assoc</code> exist: <code>assoc-if</code> expects a predicate function testing 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 with the first entry generating <code>NIL</code>.
<
;; Find the first entry whose key equals "John Doe".
(assoc-if
Line 777:
(member key '("Sally Smart" "John Doe") :test #'string=))
phone-book)
</syntaxhighlight>
The inverse process, the detection of an entry by its value, utilizes <code>rassoc</code>.
<
;; 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>
The corresponding generalizations <code>rassoc-if</code> and <code>rassoc-if-not</code> exist.
<
;; Finds the first entry whose value is "555-9999".
(rassoc-if
Line 801:
(string= value "555-9999"))
phone-book)
</syntaxhighlight>
All of the above explicated entry search functions can be replaced by general list-centric variants, that is, <code>find</code>, <code>find-if</code>, <code>find-if-not</code>, as well as pertinent functions like <code>position</code> and its derivates.
<
;; Find an entry with the key "John Doe" and the value "555-1212".
(find (cons "John Doe" "555-1212") phone-book :test #'equal)
</syntaxhighlight>
Deletion, lacking a specific counterpart, is based upon the list facilities, including destructive ones.
<
;; Create and return an alist without any entry whose key equals "John Doe".
(remove-if
Line 818:
(string= (car entry) "John Doe"))
phone-book)
</syntaxhighlight>
Iteration is accomplished by aid of any function expecting a list.
<
;; Iterate via "map".
(map NIL
Line 834:
(destructuring-bind (key . value) entry
(format T "~&~s => ~s" key value)))
</syntaxhighlight>
Being a particularly structured list, processing and transformation operations can be applied without constraints.
<
;; Return a vector of the "phone-book" values.
(map 'vector #'cdr phone-book)
Line 848:
(cons (reverse key) (reverse value))))
phone-book)
</syntaxhighlight>
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 in the fact that Common Lisp hash tables do not, as opposed to association lists, maintain the order of entry insertion.
Line 854:
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 in a single hash table instance, the specification of this key <code>:test</code> function confines the distinguishable entities: The 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.
<
(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>
The <code>gethash</code> function permits obtention of the value associated with a key.
<
(gethash "John Doe" phone-book)
</syntaxhighlight>
Additionally, an optional default value for the case of an absent key may be specified.
<
(gethash "Incognito" phone-book 'no-such-key)
</syntaxhighlight>
An invocation of <code>gethash</code> actually returns two values: the value or substitute value for the key and a boolean indicator resolving to <code>T</code> if the hash table contains the key and <code>NIL</code> to signal its absence.
<
(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>
Use <code>remhash</code> for deleting the entry associated with a key.
<
(remhash "J. Random Hacker" phone-book)
</syntaxhighlight>
<code>clrhash</code> empties the complete hash table.
<
(clrhash phone-book)
</syntaxhighlight>
The dedicated <code>maphash</code> function is specialized on iterating hash tables.
<
(maphash
#'(lambda (key value)
(format T "~&~s => ~s" key value))
phone-book)
</syntaxhighlight>
Alternatively, the <code>loop</code> construct makes provisions for iterations, either over the keys, values, or the conjunctions of both.
<
;; Iterate the keys and values of the hash table.
(loop
Line 916:
for value being the hash-values of phone-book
do (print value))
</syntaxhighlight>
A further option comprises the invocation of <code>with-hash-table-iterator</code>, an iterator-creating macro, the processing of which is intended to be driven by the caller.
<
(with-hash-table-iterator (entry-generator phone-book)
(loop do
Line 927:
(format T "~&~s => ~s" key value)
(loop-finish)))))
</syntaxhighlight>
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.
Line 934:
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 use looks like:
<
mapping phone_book = ([]);
phone_book["Sally Smart"] = "555-9999";
phone_book["John Doe"] = "555-1212";
phone_book["J. Random Hacker"] = "555-1337";
</syntaxhighlight>
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>
Line 947:
LPC drivers of the "Amylaar" family implement multivalued mappings using a secondary, numeric index. (Drivers of the MudOS family do not support multivalued mappings.) Example syntax:
<
mapping phone_book = ([:2]);
phone_book["Sally Smart", 0] = "555-9999";
Line 955:
phone_book["J. Random Hacker", 0] = "555-1337";
phone_book["J. Random Hacker", 1] = "77 Massachusetts Avenue";
</syntaxhighlight>
LPC drivers modern enough to support a foreach() construct allow iteration over their mapping types using it.
Line 965:
A table literal is written as <code>{ value, key = value, [index] = value, ["non id string"] = value }</code>. For example:
<
phone_book = {
["Sally Smart"] = "555-9999",
Line 979:
-- Table and function (and other types) can also be used as keys
}
</syntaxhighlight>
If the key is a valid identifier (not a keyword), the quotes can be omitted. They are case sensitive.
Line 985:
Lookup is written using either square brackets, which always works, or dot notation, which only works for identifier keys:
<
print(aTable["John Doe"](45))
x = aTable.subTable.k
</syntaxhighlight>
You can also loop through all keys and associated values with iterators or for loops:
<
simple = { [true] = 1, [false] = 0, [3.14] = math.pi, x = 'x', ["!"] = 42 }
function FormatElement(key, value)
Line 1,008:
until k == nil
print""
</syntaxhighlight>
An entry can be removed by setting it to nil:
<
simple.x = nil
</syntaxhighlight>
Likewise, you can overwrite values or add them:
<
simple['%'] = "percent"
simple['!'] = 111
</syntaxhighlight>
=== [[Mathematica]] and [[Wolfram Language]] ===
Mathematica uses the Association<ref>{{cite web|url=https://reference.wolfram.com/language/ref/Association.html|title=Association ( <-...-> )—Wolfram Language Documentation|website=reference.wolfram.com}}</ref> expression to represent associative arrays.
<
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>
<
phonebook[[Key["Sally Smart"]]]
</syntaxhighlight>
If the keys are strings, the ''Key'' keyword is not necessary, so:
<
phonebook[["Sally Smart"]]
</syntaxhighlight>
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>
Line 1,065:
[[Cocoa (API)]] and [[GNUstep]] 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 (both explicitly or by adding to the dictionary a different object with the same key).
<
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>
To access assigned objects this command may be used:
<
id anObject = [aDictionary objectForKey:@"Sally Smart"];
</syntaxhighlight>
All keys or values can be simply enumerated using <code>NSEnumerator</code>
<
NSEnumerator *keyEnumerator = [aDictionary keyEnumerator];
id key;
Line 1,087:
// ... process it here ...
}
</syntaxhighlight>
On Mac OS X 10.5+ and iPhone OS, dictionary keys can also be enumerated more concisely using this [https://developer.apple.com/documentation/Cocoa/Reference/NSFastEnumeration_protocol/ NSFastEnumeration] construct:
<
for (id key in aDictionary) {
// ... process it here ...
}
</syntaxhighlight>
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:
<
NSDictionary *aDictionary =
[NSDictionary dictionaryWithObjectsAndKeys:
Line 1,110:
nil], @"hackers",
nil];
</syntaxhighlight>
And relevant fields can be quickly accessed using key paths:
<
id anObject = [aDictionary valueForKeyPath:@"students.Sally Smart"];
</syntaxhighlight>
=== [[OCaml]] ===
The OCaml programming language provides three different associative containers. The simplest is a list of pairs:
<
# let m = [
"Sally Smart", "555-9999";
Line 1,133:
# List.assoc "John Doe" m;;
- : string = "555-1212"
</syntaxhighlight>
The second is a polymorphic hash table:
<
# let m = Hashtbl.create 3;;
val m : ('_a, '_b) Hashtbl.t = <abstr>
Line 1,146:
# Hashtbl.find m "John Doe";;
- : string = "555-1212"
</syntaxhighlight>
The code above uses OCaml's default hash function <code>Hashtbl.hash</code>, which is defined automatically for all types. If you wanted to use your own hash function, you can use the functor interface <code>Hashtbl.Make</code> to create a module, like with <code>Map</code> below.
Line 1,152:
Finally, functional maps (represented as immutable balanced binary trees):
<
# module StringMap = Map.Make(String);;
...
Line 1,161:
# StringMap.find "John Doe" m;;
- : string = "555-1212"
</syntaxhighlight>
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 [https://web.archive.org/web/20081211233540/http://ocaml-extlib.googlecode.com/svn/doc/apiref/PMap.html PMap], where you provide the comparison function when creating the map.
Line 1,171:
The OptimJ programming language is an extension of Java 5. As java, Optimj provides maps. But, OptimJ also provides true associative arrays: java arrays are indexed with 0-based integers; associative arrays are indexed with any collection of keys.
<
String[String] phoneBook = {
"Sally Smart" -> "555-9999",
Line 1,195:
// i.e. phoneBook["John Doe"] returns "555-1212"
</syntaxhighlight>
Of course, it is possible to define multi-dimensional arrays, to mix java array and associative arrays, to mix maps and associative arrays.
<
int[String][][double] a;
java.util.Map<String[Object], Integer> b;
</syntaxhighlight>
=== [[Perl 5]] ===
Line 1,209:
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>=></code> token, which is mostly semantically identical to the comma and makes the key-value association clearer:
<
my %phone_book = (
'Sally Smart' => '555-9999',
Line 1,215:
'J. Random Hacker' => '553-1337',
);
</syntaxhighlight>
Accessing a hash element uses the syntax <code>$hash_name{$key}</code> – the key is surrounded by ''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>.
Line 1,221:
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:
<
foreach $name (keys %phone_book) {
print $name, "\n";
}
</syntaxhighlight>
One can iterate through (key, value) pairs using the <code>each</code> function:
<
while (($name, $number) = each %phone_book) {
print 'Number for ', $name, ': ', $number, "\n";
}
</syntaxhighlight>
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:
<
my $phone_book = {
'Sally Smart' => '555-9999',
Line 1,243:
'J. Random Hacker' => '553-1337',
};
</syntaxhighlight>
Values in a hash reference are accessed using the dereferencing operator:
<
print $phone_book->{'Sally Smart'};
</syntaxhighlight>
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:
<
foreach $name (keys %{$phone_book}) {
print 'Number for ', $name, ': ', $phone_book->{$name}, "\n";
}
</syntaxhighlight>
=== [[Raku (programming language)|Raku]] ===
Line 1,264:
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>=></code> token, which makes the key-value association clearer:
<
my %phone-book =
'Sally Smart' => '555-9999',
Line 1,270:
'J. Random Hacker' => '553-1337',
;
</syntaxhighlight>
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>.
Line 1,276:
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:
<
for %phone-book.keys -> $name {
say $name;
}
</syntaxhighlight>
By default, when iterating over a ''hash'', one gets key/value ''Pair''s.
<
for %phone-book -> $entry {
say "Number for $entry.key(): $entry.value()"; # using extended interpolation features
}
</syntaxhighlight>
It's also possible to get alternating key and value values by using the ''kv'' method:
<
for %phone-book.kv -> $name, $number {
say "Number for $name: $number";
}
</syntaxhighlight>
[[Raku (programming language)|Raku]] doesn't have any references. Hashes can be passed around as single parameters that do not get flattened. If you want to make sure that a subroutine only accepts hashes, use the ''%'' sigil in the ''Signature''.
<
sub list-phone-book(%pb) {
for %pb.kv -> $name, $number {
Line 1,307:
}
list-phone-book(%phone-book);
</syntaxhighlight>
Compliant with the sense of [[gradual typing]], hashes may be subjected to type constraints, confining the set of valid keys to a certain type.
<
# Define a hash whose keys may only be integer numbers ("Int" type).
my %numbersWithNames{Int};
Line 1,320:
# This will cause an error, as strings as keys are invalid.
%numbersWithNames.push("key" => "two");
</syntaxhighlight>
=== [[PHP]] ===
Line 1,327:
An associative array can be declared using the following syntax:
<
$phonebook = array();
$phonebook['Sally Smart'] = '555-9999';
Line 1,354:
$phonebook['contacts']['John Doe']['number'] = '555-1212';
$phonebook['contacts']['J. Random Hacker']['number'] = '555-1337';
</syntaxhighlight>
PHP can loop through an associative array as follows:
<
foreach($phonebook as $name => $number) {
echo 'Number for ', $name, ': ', $number, "\n";
Line 1,367:
echo 'Name: ', $name, ', number: ', $num['number'], "\n";
}
</syntaxhighlight>
PHP has an [http://php.net/array extensive set of functions] to operate on arrays.
Line 1,376:
Pike has built-in support for Associative Arrays, which are referred to as mappings. Mappings are created as follows:
<
mapping(string:string) phonebook = ([
"Sally Smart":"555-9999",
Line 1,382:
"J. Random Hacker":"555-1337"
]);
</syntaxhighlight>
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.
Line 1,388:
Iterating through a mapping can be done using either foreach:
<
foreach(phonebook; string key; string value) {
write("%s:%s\n", key, value);
}
</syntaxhighlight>
Or using an iterator object:
<
Mapping.Iterator i = get_iterator(phonebook);
while (i->index()) {
Line 1,402:
i->next();
}
</syntaxhighlight>
Elements of a mapping can be removed using m_delete, which returns the value of the removed index:
<
string sallys_number = m_delete(phonebook, "Sally Smart");
</syntaxhighlight>
=== PostScript ===
In [[PostScript]], associative arrays are called dictionaries. In Level 1 PostScript they must be created explicitly, but Level 2 introduced direct declaration using the double-brace syntax:
<
% Level 1 declaration
3 dict dup begin
Line 1,429:
% Both methods leave the dictionary on the operand stack
</syntaxhighlight>
Dictionaries can be accessed directly using '''get''' or implicitly by placing the dictionary on the dictionary stack using '''begin''':
<
% With the previous two dictionaries still on the operand stack
/red get print % outputs 'rot'
Line 1,439:
green print % outputs 'vert'
end
</syntaxhighlight>
Dictionary contents can be iterated through using '''forall''', though not in any particular order:
<
% Level 2 example
<<
Line 1,450:
/Other 3
>> {exch =print ( is ) print ==} forall
</syntaxhighlight>
May well output:
<
That is 2
This is 1
Other is 3
</syntaxhighlight>
Dictionaries can be augmented (up to their defined size only in Level 1) or altered using '''put''', and entries can be removed using '''undef''':
<
% define a dictionary for easy reuse:
/MyDict <<
Line 1,474:
% remove something
MyDict /rouge undef
</syntaxhighlight>
=== Prolog ===
Line 1,485:
In Python, associative arrays are called ''[[Python syntax and semantics#Collection types|dictionaries]]''. Dictionary literals are marked with curly braces:
<
phonebook = {
'Sally Smart': '555-9999',
Line 1,491:
'J. Random Hacker': '553-1337',
}
</syntaxhighlight>
To access an entry in Python simply use the array indexing operator. For example,
<
>>> phonebook['Sally Smart']
'555-9999'
</syntaxhighlight>
An example loop [[iterator#Python|iterating]] through all the keys of the dictionary:
<
>>> for key in phonebook:
... print(key, phonebook[key])
Line 1,506:
J. Random Hacker 553-1337
John Doe 555-1212
</syntaxhighlight>
Iterating through (key, value) tuples:
<
>>> for key, value in phonebook.items():
... print(key, value)
Line 1,516:
J. Random Hacker 553-1337
John Doe 555-1212
</syntaxhighlight>
Dictionary keys can be individually deleted using the del statement. The corresponding value can be returned before the key-value pair are deleted using the pop method of dict types:
<
>>> del phonebook['John Doe']
>>> val = phonebook.pop('Sally Smart')
>>> phonebook.keys() # Only one key left
['J. Random Hacker']
</syntaxhighlight>
Python 2.7 and 3.x also supports dictionary comprehensions, a compact syntax for generating a dictionary from any iterator:
<
>>> square_dict = {i: i*i for i in range(5)}
>>> square_dict
Line 1,534:
>>> {key: value for key, value in phonebook.items() if 'J' in key}
{'J. Random Hacker': '553-1337', 'John Doe': '555-1212'}
</syntaxhighlight>
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:
<
phonebook = {
'Sally Smart': '555-9999',
Line 1,545:
14: '555-3322',
}
</syntaxhighlight>
The dictionary keys must be of an [[Immutable object|immutable]] data type. In Python, strings are immutable due to their method of implementation.
Line 1,554:
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:
<
my-map: make map! [
"Sally Smart" "555-9999"
Line 1,560:
"J. Random Hacker" "553-1337"
]
</syntaxhighlight>
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>.
Line 1,566:
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.
<
my-other-map: make map! [foo: 42 bar: false]
</syntaxhighlight>
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:
<
my-other-map: make map! [foo: 42 bar: #[false]]
</syntaxhighlight>
or keys can be added after creation:
<
my-other-map: make map! [foo: 42]
my-other-map/bar: false
</syntaxhighlight>
Lookup can be written using <code>path!</code> notation or using the <code>select</code> action:
<
select my-map "Sally Smart"
my-other-map/foo
</syntaxhighlight>
You can also loop through all keys and values with <code>foreach</code>:
<
foreach [key value] my-map [
print [key "is associated to" value]
]
</syntaxhighlight>
A key can be removed using <code>remove/key</code>:
<
remove/key my-map "Sally Smart"
</syntaxhighlight>
=== [[REXX]] ===
In REXX, associative arrays are called ''Stem variables'' or ''Compound variables''.
<
KEY = 'Sally Smart'
PHONEBOOK.KEY = '555-9999'
Line 1,614:
KEY = 'J. Random Hacker'
PHONEBOOK.KEY = '553-1337'
</syntaxhighlight>
Stem variables with numeric keys typically start at 1 and go up from there. The 0 key stem variable
is used (by convention) as the count of items in the whole stem.
<
NAME.1 = 'Sally Smart'
NAME.2 = 'John Doe'
NAME.3 = 'J. Random Hacker'
NAME.0 = 3
</syntaxhighlight>
REXX has no easy way of automatically accessing the keys for a stem variable and typically the
Line 1,633:
In Ruby a [[hash table|hash]] is used as follows:
<
irb(main):001:0> phonebook = {
irb(main):002:1* 'Sally Smart' => '555-9999',
Line 1,642:
irb(main):006:0> phonebook['John Doe']
=> "555-1212"
</syntaxhighlight>
Ruby supports hash looping and iteration with the following syntax:
<
irb(main):007:0> ### iterate over keys and values
irb(main):008:0* phonebook.each {|key, value| puts key + " => " + value}
Line 1,665:
553-1337
=> {"Sally Smart"=>"555-9999", "John Doe"=>"555-1212", "J. Random Hacker"=>"553-1337"}
</syntaxhighlight>
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.
Line 1,674:
For example:
<
phonebook = Assoc_Type[];
phonebook["Sally Smart"] = "555-9999"
phonebook["John Doe"] = "555-1212"
phonebook["J. Random Hacker"] = "555-1337"
</syntaxhighlight>
You can also loop through an associated array in a number of ways.
Here is one
<
foreach name (phonebook) {
vmessage ("%s %s", name, phonebook[name]);
}
</syntaxhighlight>
To print a sorted-list, it is better to take advantage of S-lang's strong
support for standard arrays:
<
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>
=== [[Scala (programming language)|Scala]] ===
Scala provides an immutable Map class as part of the scala.collection framework:
<
val phonebook = Map("Sally Smart" -> "555-9999",
"John Doe" -> "555-1212",
"J. Random Hacker" -> "553-1337")
</syntaxhighlight>
Scala's [[type inference]] will work out that this is a <code>Map[String, String]</code>. To access the array:
<
phonebook.get("Sally Smart")
</syntaxhighlight>
This returns an Option type, Scala's equivalent of a [[Monad (functional programming)#The Maybe monad|the Maybe monad]] in Haskell.
Line 1,720:
In Smalltalk a dictionary is used:
<
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>
To access an entry the message <code>#at:</code> is sent to the dictionary object.
<
phonebook at: 'Sally Smart'
</syntaxhighlight>
gives
<
'555-9999'
</syntaxhighlight>
Dictionary hashes/compares based on equality and holds
[[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).
Line 1,746:
Associative arrays in [[SNOBOL]] are called Tables.
<
PHONEBOOK = TABLE()
PHONEBOOK['Sally Smart'] = '555-9999'
PHONEBOOK['John Doe'] = '555-1212'
PHONEBOOK['J. Random Hacker'] = '553-1337'
</syntaxhighlight>
=== [[Standard ML]] ===
Line 1,758:
The library of the popular [[Standard ML of New Jersey]] 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, <code>BinaryMapFn</code>, <code>ListMapFn</code>, <code>RedBlackMapFn</code>, and <code>SplayMapFn</code>, that allow you to create the corresponding type of ordered map (the types are a [[self-balancing binary search tree]], sorted [[association list]], [[red-black tree]], and [[splay tree]], respectively) using a user-provided structure to describe the key type and comparator. The functor returns a structure that follows the <code>ORD_MAP</code> interface. In addition, there are two pre-defined modules for associative arrays with integer keys: <code>IntBinaryMap</code> and <code>IntListMap</code>.
<
- structure StringMap = BinaryMapFn (struct
type ord_key = string
Line 1,776:
- StringMap.find (m, "John Doe");
val it = SOME "555-1212" : string option
</syntaxhighlight>
SML/NJ also provides a polymorphic hash table:
<
- exception NotFound;
exception NotFound
Line 1,799:
- HashTable.lookup m "John Doe"; (* raises the exception if not found *)
val it = "555-1212" : string
</syntaxhighlight>
Monomorphic hash tables are also supported using the <code>HashTableFn</code> functor.
Line 1,810:
====dict====
<
set phonebook [dict create {Sally Smart} 555-9999 {John Doe} 555-1212 {J. Random Hacker} 553-1337]
</syntaxhighlight>
To look up an item:
<
dict get $phonebook {John Doe}
</syntaxhighlight>
To iterate through a dict:
<
foreach {name number} $phonebook {
puts "name: $name\nnumber: $number"
}
</syntaxhighlight>
====array====
<
set {phonebook(Sally Smart)} 555-9999
set john {John Doe}
set phonebook($john) 555-1212
set {phonebook(J. Random Hacker)} 553-1337
</syntaxhighlight>
If there is a literal space character in the variable name, it must be grouped using either curly brackets (no substitution performed) or double quotes (substitution is performed).
Line 1,841:
Alternatively, several array elements can be set in a single command by providing their mappings as a list (words containing whitespace are braced):
<
array set phonebook [list {Sally Smart} 555-9999 {John Doe} 555-1212 {J. Random Hacker} 553-1337]
</syntaxhighlight>
To access one array entry and put it on standard output
<
puts $phonebook(Sally\ Smart)
</syntaxhighlight>
The result is here
<
555-9999
</syntaxhighlight>
To retrieve the entire array as a dictionary:
<
array get phonebook
</syntaxhighlight>
The result can be (order of keys is unspecified, not because the dictionary is unordered, but because the array is):
<
{Sally Smart} 555-9999 {J. Random Hacker} 553-1337 {John Doe} 555-1212
</syntaxhighlight>
=== [[Visual Basic]] ===
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):
<
' Requires a reference to SCRRUN.DLL in Project Properties
Dim phoneBook As New Dictionary
Line 1,881:
MsgBox name & " = " & phoneBook(name)
Next
</syntaxhighlight>
=== [[Visual Basic .NET]] ===
Line 1,889:
The following code demonstrates the creation and population of a dictionary. See [[#C#|the C# example on this page]] for additional information.
<
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>
An alternative syntax would be to use a ''collection initializer'', which compiles down to individual calls to <code>Add</code>.
<
Dim dic As New System.Collections.Dictionary(Of String, String) From {
{"Sally Smart", "555-9999"},
Line 1,903:
{"J. Random Hacker", "553-1337"}
}
</syntaxhighlight>
====Access by key====
Example demonstrating access; see [[#C# access|this section of the C# example]] for explanation:
<
Dim sallyNumber = dic("Sally Smart")
' or
Dim sallyNumber = dic.Item("Sally Smart")
</syntaxhighlight>
<
Dim result As String = Nothing
Dim sallyNumber = If(dic.TryGetValue("Sally Smart", result), result, "n/a")
</syntaxhighlight>
====Enumeration====
Example demonstrating enumeration; see [[#C# enumeration|this section of the C# example]] for explanation:
<
' 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>
=== [[Windows PowerShell]] ===
Line 1,933:
For example:
<
$phonebook = @{
'Sally Smart' = '555-9999';
Line 1,939:
'J. Random Hacker' = '553-1337'
}
</syntaxhighlight>
Like in JavaScript, if the property name is a valid identifier, the quotes can be omitted, e.g.:
<
$myOtherObject = @{ foo = 42; bar = $false }
</syntaxhighlight>
Entries can be separated by either a semicolon or a newline, e.g.:
<
$myOtherObject = @{ foo = 42
bar = $false ;
zaz = 3
}
</syntaxhighlight>
Keys and values can be any [[.NET Framework|.NET]] object type, e.g.:
<
$now = [DateTime]::Now
$tomorrow = $now.AddDays(1)
Line 1,965:
(Get-Process calc) = $tomorrow
}
</syntaxhighlight>
It is also possible to create an empty associative array and add single entries or even other associative arrays to it later on.
<
$phonebook = @{}
$phonebook += @{ 'Sally Smart' = '555-9999' }
$phonebook += @{ 'John Doe' = '555-1212'; 'J. Random Hacker' = '553-1337' }
</syntaxhighlight>
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:
<
$phonebook = @{}
$phonebook['Sally Smart'] = '555-9999'
$phonebook.'John Doe' = '555-1212'
$phonebook.Add('J. Random Hacker', '553-1337')
</syntaxhighlight>
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:
<
$phonebook['Sally Smart']
$phonebook.'John Doe'
$phonebook.Item('J. Random Hacker')
</syntaxhighlight>
You can loop through an associative array as follows:
<
$phonebook.Keys | foreach { "Number for {0}: {1}" -f $_,$phonebook.$_ }
</syntaxhighlight>
An entry can be removed using the <code>Remove()</code> method of the underlying .NET object:
<
$phonebook.Remove('Sally Smart')
</syntaxhighlight>
Hash tables can be added, e.g.:
<
$hash1 = @{ a=1; b=2 }
$hash2 = @{ c=3; d=4 }
$hash3 = $hash1 + $hash2
</syntaxhighlight>
==Data serialization formats support==
Line 2,019:
=== [[JSON]] ===
In JSON, associative arrays are also referred to as objects. Keys can only be strings.
<
{
"Sally Smart": "555-9999",
Line 2,025:
"J. Random Hacker": "555-1337"
}
</syntaxhighlight>
=== [[YAML]] ===
Line 2,031:
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.
<
Sally Smart: 555-9999
John Doe: 555-1212
J. Random Hacker: 555-1337
</syntaxhighlight>
== References ==
|