Comparison of programming languages (associative array)This comparison of programming languages (associative arrays) compares the features of associative array data structures or array-lookup processing for over 40 computer programming languages. Language supportThe following is a comparison of associative arrays (also "mapping", "hash", and "dictionary") in various programming languages. AWKAWK has built-in, language-level support for associative arrays. For example: phonebook["Sally Smart"] = "555-9999"
phonebook["John Doe"] = "555-1212"
phonebook["J. Random Hacker"] = "555-1337"
The following code loops through an associated array and prints its contents: for (name in phonebook) {
print name, " ", phonebook[name]
}
The user can search for elements in an associative array, and delete elements from the array. The following shows how multi-dimensional associative arrays can be simulated in standard AWK using concatenation and the built-in string-separator variable SUBSEP: { # for every input line
multi[$1 SUBSEP $2]++;
}
#
END {
for (x in multi) {
split(x, arr, SUBSEP);
print arr[1], arr[2], multi[x];
}
}
CThere is no standard implementation of associative arrays in C, but a 3rd-party library, C Hash Table, with BSD license, is available.[1] Another 3rd-party library, uthash, also creates associative arrays from C structures. A structure represents a value, and one of the structure fields serves as the key.[2] Finally, the GLib library also supports associative arrays, along with many other advanced data types and is the recommended implementation of the GNU Project.[3] Similar to GLib, Apple's cross-platform Core Foundation framework provides several basic data types. In particular, there are reference-counted CFDictionary and CFMutableDictionary. C#C# uses the collection classes provided by the .NET Framework. The most commonly used associative array type is CreationThe following demonstrates three means of populating a mutable dictionary:
var dictionary = new Dictionary<string, string>();
dictionary.Add("Sally Smart", "555-9999");
dictionary["John Doe"] = "555-1212";
// Not allowed in C#.
// dictionary.Item("J. Random Hacker") = "553-1337";
dictionary["J. Random Hacker"] = "553-1337";
The dictionary can also be initialized during construction using a "collection initializer", which compiles to repeated calls to var dictionary = new Dictionary<string, string> {
{ "Sally Smart", "555-9999" },
{ "John Doe", "555-1212" },
{ "J. Random Hacker", "553-1337" }
};
Access by keyValues are primarily retrieved using the indexer (which throws an exception if the key does not exist) and the var sallyNumber = dictionary["Sally Smart"];
var sallyNumber = (dictionary.TryGetValue("Sally Smart", out var result) ? result : "n/a";
In this example, the EnumerationA 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 The following demonstrates enumeration using a foreach loop: // loop through the collection and display each entry.
foreach (KeyValuePair<string,string> kvp in dictionary)
{
Console.WriteLine("Phone number for {0} is {1}", kvp.Key, kvp.Value);
}
C++C++ has a form of associative array called #include <map>
#include <string>
#include <utility>
int main() {
std::map<std::string, std::string> phone_book;
phone_book.insert(std::make_pair("Sally Smart", "555-9999"));
phone_book.insert(std::make_pair("John Doe", "555-1212"));
phone_book.insert(std::make_pair("J. Random Hacker", "553-1337"));
}
Or less efficiently, as this creates temporary #include <map>
#include <string>
int main() {
std::map<std::string, std::string> phone_book;
phone_book["Sally Smart"] = "555-9999";
phone_book["John Doe"] = "555-1212";
phone_book["J. Random Hacker"] = "553-1337";
}
With the extension of initialization lists in C++11, entries can be added during a map's construction as shown below: #include <map>
#include <string>
int main() {
std::map<std::string, std::string> phone_book {
{"Sally Smart", "555-9999"},
{"John Doe", "555-1212"},
{"J. Random Hacker", "553-1337"}
};
}
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;
The same task in C++11: for(const auto& curr : phone_book)
std::cout << curr.first << " = " << curr.second << std::endl;
Using the structured binding available in C++17: for (const auto& [name, number] : phone_book) {
std::cout << name << " = " << number << std::endl;
}
In C++, the CobraInitializing an empty dictionary and adding items in Cobra: dic as Dictionary<of String, String> = Dictionary<of String, String>()
dic.add('Sally Smart', '555-9999')
dic.add('John Doe', '555-1212')
dic.add('J. Random Hacker', '553-1337')
assert dic['Sally Smart'] == '555-9999'
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]"
ColdFusion Markup LanguageA structure in ColdFusion Markup Language (CFML) is equivalent to an associative array: dynamicKeyName = "John Doe";
phoneBook = {
"Sally Smart" = "555-9999",
"#dynamicKeyName#" = "555-4321",
"J. Random Hacker" = "555-1337",
UnknownComic = "???"
};
writeOutput(phoneBook.UnknownComic); // ???
writeDump(phoneBook); // entire struct
DD offers direct support for associative arrays in the core language; such arrays are implemented as a chaining hash table with binary trees.[4] The equivalent example would be: int main() {
string[ string ] phone_book;
phone_book["Sally Smart"] = "555-9999";
phone_book["John Doe"] = "555-1212";
phone_book["J. Random Hacker"] = "553-1337";
return 0;
}
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. Looping through all properties and associated values, and printing them, can be coded as follows: foreach (key, value; phone_book) {
writeln("Number for " ~ key ~ ": " ~ value );
}
A property can be removed as follows: phone_book.remove("Sally Smart");
DelphiDelphi supports several standard containers, including TDictionary<T>: uses
SysUtils,
Generics.Collections;
var
PhoneBook: TDictionary<string, string>;
Entry: TPair<string, string>;
begin
PhoneBook := TDictionary<string, string>.Create;
PhoneBook.Add('Sally Smart', '555-9999');
PhoneBook.Add('John Doe', '555-1212');
PhoneBook.Add('J. Random Hacker', '553-1337');
for Entry in PhoneBook do
Writeln(Format('Number for %s: %s',[Entry.Key, Entry.Value]));
end.
Pre-2009 Delphi versions do not support associative arrays directly. Such arrays can be simulated using the TStrings class: procedure TForm1.Button1Click(Sender: TObject);
var
DataField: TStrings;
i: Integer;
begin
DataField := TStringList.Create;
DataField.Values['Sally Smart'] := '555-9999';
DataField.Values['John Doe'] := '555-1212';
DataField.Values['J. Random Hacker'] := '553-1337';
// access an entry and display it in a message box
ShowMessage(DataField.Values['Sally Smart']);
// loop through the associative array
for i := 0 to DataField.Count - 1 do
begin
ShowMessage('Number for ' + DataField.Names[i] + ': ' + DataField.ValueFromIndex[i]);
end;
DataField.Free;
end;
ErlangErlang offers many ways to represent mappings; three of the most common in the standard library are keylists, dictionaries, and maps. KeylistsKeylists 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 PhoneBook = [{"Sally Smith", "555-9999"},
{"John Doe", "555-1212"},
{"J. Random Hacker", "553-1337"}].
Accessing an element of the keylist can be done with the {_, Phone} = lists:keyfind("Sally Smith", 1, PhoneBook),
io:format("Phone number: ~s~n", [Phone]).
DictionariesDictionaries are implemented in the 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).
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"}]).
The dictionary can be accessed using the {ok, Phone} = dict:find("Sally Smith", PhoneBook),
io:format("Phone: ~s~n", [Phone]).
In both cases, any Erlang term can be used as the key. Variations include the MapsMaps were introduced in OTP 17.0,[5] and combine the strengths of keylists and dictionaries. A map is defined using the syntax PhoneBook = #{"Sally Smith" => "555-9999",
"John Doe" => "555-1212",
"J. Random Hacker" => "553-1337"}.
Basic functions to interact with maps are available from the {ok, Phone} = maps:find("Sally Smith", PhoneBook),
io:format("Phone: ~s~n", [Phone]).
Unlike dictionaries, maps can be pattern matched upon: #{"Sally Smith", Phone} = PhoneBook,
io:format("Phone: ~s~n", [Phone]).
Erlang also provides syntax sugar for functional updates—creating a new map based on an existing one, but with modified values or additional keys: 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"
}
F#Map<'Key,'Value>At runtime, F# provides the CreationThe following example calls the let numbers =
[
"Sally Smart", "555-9999";
"John Doe", "555-1212";
"J. Random Hacker", "555-1337"
] |> Map
Access by keyValues can be looked up via one of the let sallyNumber = numbers.["Sally Smart"]
// or
let sallyNumber = numbers.Item("Sally Smart")
let sallyNumber =
match numbers.TryFind("Sally Smart") with
| Some(number) -> number
| None -> "n/a"
In both examples above, the Dictionary<'TKey,'TValue>Because F# is a .NET language, it also has access to features of the .NET Framework, including the CreationThe let numbers =
[
"Sally Smart", "555-9999";
"John Doe", "555-1212";
"J. Random Hacker", "555-1337"
] |> dict
When a mutable dictionary is needed, the constructor of 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"
Access by key
let sallyNumber =
let mutable result = ""
if numbers.TryGetValue("Sally Smart", &result) then result else "n/a"
F# 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"
EnumerationA dictionary or map can be enumerated using // loop through the collection and display each entry.
numbers |> Seq.map (fun kvp -> printfn "Phone number for %O is %O" kvp.Key kvp.Value)
FoxProVisual FoxPro implements mapping with the Collection Class. mapping = NEWOBJECT("Collection")
mapping.Add("Daffodils", "flower2") && Add(object, key) – key must be character
index = mapping.GetKey("flower2") && returns the index value 1
object = mapping("flower2") && returns "Daffodils" (retrieve by key)
object = mapping(1) && returns "Daffodils" (retrieve by index)
GetKey returns 0 if the key is not found. GoGo 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: 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"
A map literal: phone_book := map[string] string {
"Sally Smart": "555-9999",
"John Doe": "555-1212",
"J. Random Hacker": "553-1337",
}
Iterating through a map: // over both keys and values
for key, value := range phone_book {
fmt.Printf("Number for %s: %s\n", key, value)
}
// over just keys
for key := range phone_book {
fmt.Printf("Name: %s\n", key)
}
HaskellThe Haskell programming language provides only 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)
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), the most commonly used implementation of Haskell, provides two more types of associative containers. Other implementations may also provide these. One is polymorphic functional maps (represented as immutable balanced binary trees): import qualified Data.Map as M
m = M.insert "Sally Smart" "555-9999" M.empty
m' = M.insert "John Doe" "555-1212" m
m'' = M.insert "J. Random Hacker" "553-1337" m'
main = print (M.lookup "John Doe" m'' :: Maybe String)
output: Just "555-1212" A specialized version for integer keys also exists as Data.IntMap. Finally, a polymorphic hash table: import qualified Data.HashTable as H
main = do m <- H.new (==) H.hashString
H.insert m "Sally Smart" "555-9999"
H.insert m "John Doe" "555-1212"
H.insert m "J. Random Hacker" "553-1337"
foo <- H.lookup m "John Doe"
print foo
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 IO monad. JavaIn Java associative arrays are implemented as "maps", which are part of the Java collections framework. Since J2SE 5.0 and the introduction of generics into Java, collections can have a type specified; for example, an associative array that maps 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");
The The hash function in Java, used by HashMap and HashSet, is provided by the The For two objects a and b, a.equals(b) == b.equals(a)
if a.equals(b), then a.hashCode() == b.hashCode()
In order to maintain this contract, a class that overrides A further contract that a hashed data structure has with the object is that the results of the Analogously, TreeMap, and other sorted data structures, require that an ordering be defined on the data type. Either the data type must already have defined its own ordering, by implementing the JavaScriptJavaScript (and its standardized version, ECMAScript) is a prototype-based object-oriented language. Map and WeakMapModern JavaScript handles associative arrays, using the CreationA map can be initialized with all items during construction: const phoneBook = new Map([
["Sally Smart", "555-9999"],
["John Doe", "555-1212"],
["J. Random Hacker", "553-1337"],
]);
Alternatively, you can initialize an empty map and then add items: const phoneBook = new Map();
phoneBook.set("Sally Smart", "555-9999");
phoneBook.set("John Doe", "555-1212");
phoneBook.set("J. Random Hacker", "553-1337");
Access by keyAccessing an element of the map can be done with the const sallyNumber = phoneBook.get("Sally Smart");
In this example, the value EnumerationThe 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: // loop through the collection and display each entry.
for (const [name, number] of phoneBook) {
console.log(`Phone number for ${name} is ${number}`);
}
A key can be removed as follows: phoneBook.delete("Sally Smart");
ObjectAn 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 const myObject = {
"Sally Smart": "555-9999",
"John Doe": "555-1212",
"J. Random Hacker": "553-1337",
};
To prevent the lookup from using the prototype's properties, you can use the Object.setPrototypeOf(myObject, null);
As of ECMAScript 5 (ES5), the prototype can also be bypassed by using const myObject = Object.create(null);
Object.assign(myObject, {
"Sally Smart": "555-9999",
"John Doe": "555-1212",
"J. Random Hacker": "553-1337",
});
If the property name is a valid identifier, the quotes can be omitted, e.g.: const myOtherObject = { foo: 42, bar: false };
Lookup is written using property-access notation, either square brackets, which always work, or dot notation, which only works for identifier keys: myObject["John Doe"]
myOtherObject.foo
You can also loop through all enumerable properties and associated values as follows (a for-in loop): for (const property in myObject) {
const value = myObject[property];
console.log(`myObject[${property}] = ${value}`);
}
Or (a for-of loop): for (const [property, value] of Object.entries(myObject)) {
console.log(`${property} = ${value}`);
}
A property can be removed as follows: delete myObject["Sally Smart"];
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() { return "hello world"; } }] // key is "hello world"
In modern JavaScript it's considered bad form to use the Array type as an associative array. Consensus is that the Object type and See JavaScript Array And Object Prototype Awareness Day for more information on the issue. JuliaIn Julia, the following operations manage associative arrays. Declare dictionary: phonebook = Dict( "Sally Smart" => "555-9999", "John Doe" => "555-1212", "J. Random Hacker" => "555-1337" )
Access element: phonebook["Sally Smart"]
Add element: phonebook["New Contact"] = "555-2222"
Delete element: delete!(phonebook, "Sally Smart")
Get keys and values as iterables: keys(phonebook)
values(phonebook)
KornShell 93, and compliant shellsIn KornShell 93, and compliant shells (ksh93, bash4...), the following operations can be used with associative arrays. Definition: 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");
Dereference: ${phonebook["John Doe"]};
LispLisp 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"))
The syntax 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 (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)))
This function can be construed as an accommodation for ;; The effect of
;; (cons (cons KEY VALUE) ALIST)
;; is equivalent to
;; (acons KEY VALUE ALIST)
(let ((phone-book '(("Sally Smart" . "555-9999") ("John Doe" . "555-1212"))))
(cons (cons "J. Random Hacker" "555-1337") phone-book))
Of course, the destructive (push (cons "Dummy" "123-4567") phone-book)
Searching for an entry by its key is performed via (assoc "John Doe" phone-book :test #'string=)
Two generalizations of ;; Find the first entry whose key equals "John Doe".
(assoc-if
#'(lambda (key)
(string= key "John Doe"))
phone-book)
;; Finds the first entry whose key is neither "Sally Smart" nor "John Doe"
(assoc-if-not
#'(lambda (key)
(member key '("Sally Smart" "John Doe") :test #'string=))
phone-book)
The inverse process, the detection of an entry by its value, utilizes ;; 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=)
The corresponding generalizations ;; Finds the first entry whose value is "555-9999".
(rassoc-if
#'(lambda (value)
(string= value "555-9999"))
phone-book)
;; Finds the first entry whose value is not "555-9999".
(rassoc-if-not
#'(lambda (value)
(string= value "555-9999"))
phone-book)
All of the previous entry search functions can be replaced by general list-centric variants, such as ;; Find an entry with the key "John Doe" and the value "555-1212".
(find (cons "John Doe" "555-1212") phone-book :test #'equal)
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
#'(lambda (entry)
(string= (car entry) "John Doe"))
phone-book)
Iteration is accomplished with the aid of any function that expects a list. ;; Iterate via "map".
(map NIL
#'(lambda (entry)
(destructuring-bind (key . value) entry
(format T "~&~s => ~s" key value)))
phone-book)
;; Iterate via "dolist".
(dolist (entry phone-book)
(destructuring-bind (key . value) entry
(format T "~&~s => ~s" key value)))
These being structured lists, processing and transformation operations can be applied without constraints. ;; Return a vector of the "phone-book" values.
(map 'vector #'cdr phone-book)
;; Destructively modify the "phone-book" via "map-into".
(map-into phone-book
#'(lambda (entry)
(destructuring-bind (key . value) entry
(cons (reverse key) (reverse value))))
phone-book)
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 they are implemented in SRFI 69. Hash tables have greater overhead than alists, but provide much faster access when there are many elements. A further characteristic is 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 (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"))
The (gethash "John Doe" phone-book)
Additionally, a default value for the case of an absent key may be specified. (gethash "Incognito" phone-book 'no-such-key)
An invocation of (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.")))
Use (remhash "J. Random Hacker" phone-book)
(clrhash phone-book)
The dedicated (maphash
#'(lambda (key value)
(format T "~&~s => ~s" key value))
phone-book)
Alternatively, the ;; Iterate the keys and values of the hash table.
(loop
for key being the hash-keys of phone-book
using (hash-value value)
do (format T "~&~s => ~s" key value))
;; Iterate the values of the hash table.
(loop
for value being the hash-values of phone-book
do (print value))
A further option invokes (with-hash-table-iterator (entry-generator phone-book)
(loop do
(multiple-value-bind (has-entry key value) (entry-generator)
(if has-entry
(format T "~&~s => ~s" key value)
(loop-finish)))))
It is easy to construct composite abstract data types in Lisp, using structures or object-oriented programming features, in conjunction with lists, arrays, and hash tables. LPCLPC 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 mapping phone_book = ([]);
phone_book["Sally Smart"] = "555-9999";
phone_book["John Doe"] = "555-1212";
phone_book["J. Random Hacker"] = "555-1337";
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. Deletion is accomplished using a function called either m_delete() or map_delete(), depending on the driver: LPC drivers of the Amylaar family implement multivalued mappings using a secondary, numeric index (other drivers of the MudOS family do not support multivalued mappings.) Example syntax: mapping phone_book = ([:2]);
phone_book["Sally Smart", 0] = "555-9999";
phone_book["Sally Smart", 1] = "99 Sharp Way";
phone_book["John Doe", 0] = "555-1212";
phone_book["John Doe", 1] = "3 Nigma Drive";
phone_book["J. Random Hacker", 0] = "555-1337";
phone_book["J. Random Hacker", 1] = "77 Massachusetts Avenue";
LPC drivers modern enough to support a foreach() construct use it to iterate through their mapping types. LuaIn Lua, "table" is a fundamental type that can be used either as an array (numerical index, fast) or as an 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 phone_book = {
["Sally Smart"] = "555-9999",
["John Doe"] = "555-1212",
["J. Random Hacker"] = "553-1337", -- Trailing comma is OK
}
aTable = {
-- Table as value
subTable = { 5, 7.5, k = true }, -- key is "subTable"
-- Function as value
['John Doe'] = function (age) if age < 18 then return "Young" else return "Old!" end end,
-- Table and function (and other types) can also be used as keys
}
If the key is a valid identifier (not a reserved word), the quotes can be omitted. Identifiers are case sensitive. 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
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)
return "[" .. tostring(key) .. "] = " .. value .. ", "
end
-- Iterate on all keys
table.foreach(simple, function (k, v) io.write(FormatElement(k, v)) end)
print""
for k, v in pairs(simple) do io.write(FormatElement(k, v)) end
print""
k= nil
repeat
k, v = next(simple, k)
if k ~= nil then io.write(FormatElement(k, v)) end
until k == nil
print""
An entry can be removed by setting it to nil: simple.x = nil
Likewise, you can overwrite values or add them: simple['%'] = "percent"
simple['!'] = 111
Mathematica and Wolfram LanguageMathematica and Wolfram Language use the Association expression to represent associative arrays.[7] phonebook = <| "Sally Smart" -> "555-9999",
"John Doe" -> "555-1212",
"J. Random Hacker" -> "553-1337" |>;
To access:[8] phonebook[[Key["Sally Smart"]]]
If the keys are strings, the Key keyword is not necessary, so: phonebook[["Sally Smart"]]
To list keys:[9] and values[10] Keys[phonebook] Values[phonebook] MUMPSIn 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 to multiple jobs. The name for globals is preceded by the circumflex "^" to distinguish them from local variables. 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 Accessing the value of an element simply requires using the name with the subscript: WRITE "Phone Number :",^phonebook("Sally Smart"),! You can also loop through an associated array as follows: SET NAME="" FOR S NAME=$ORDER(^phonebook(NAME)) QUIT:NAME="" WRITE NAME," Phone Number :",^phonebook(NAME),! Objective-C (Cocoa/GNUstep)Cocoa and GNUstep, written in Objective-C, handle associative arrays using 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"];
To access assigned objects, this command may be used: id anObject = [aDictionary objectForKey:@"Sally Smart"];
All keys or values can be enumerated using NSEnumerator *keyEnumerator = [aDictionary keyEnumerator];
id key;
while ((key = [keyEnumerator nextObject]))
{
// ... process it here ...
}
In Mac OS X 10.5+ and iPhone OS, dictionary keys can be enumerated more concisely using the for (id key in aDictionary) {
// ... process it here ...
}
What is even more practical, structured data graphs may be easily created using Cocoa, especially NSDictionary *aDictionary =
[NSDictionary dictionaryWithObjectsAndKeys:
[NSDictionary dictionaryWithObjectsAndKeys:
@"555-9999", @"Sally Smart",
@"555-1212", @"John Doe",
nil], @"students",
[NSDictionary dictionaryWithObjectsAndKeys:
@"553-1337", @"Random Hacker",
nil], @"hackers",
nil];
Relevant fields can be quickly accessed using key paths: id anObject = [aDictionary valueForKeyPath:@"students.Sally Smart"];
OCamlThe OCaml programming language provides three different associative containers. The simplest is a list of pairs: # let m = [
"Sally Smart", "555-9999";
"John Doe", "555-1212";
"J. Random Hacker", "553-1337"];;
val m : (string * string) list = [
("Sally Smart", "555-9999");
("John Doe", "555-1212");
("J. Random Hacker", "553-1337")
]
# List.assoc "John Doe" m;;
- : string = "555-1212"
The second is a polymorphic hash table: # let m = Hashtbl.create 3;;
val m : ('_a, '_b) Hashtbl.t = <abstr>
# Hashtbl.add m "Sally Smart" "555-9999";
Hashtbl.add m "John Doe" "555-1212";
Hashtbl.add m "J. Random Hacker" "553-1337";;
- : unit = ()
# Hashtbl.find m "John Doe";;
- : string = "555-1212"
The code above uses OCaml's default hash function Finally, functional maps (represented as immutable balanced binary trees): # module StringMap = Map.Make(String);;
...
# let m = StringMap.add "Sally Smart" "555-9999" StringMap.empty
let m = StringMap.add "John Doe" "555-1212" m
let m = StringMap.add "J. Random Hacker" "553-1337" m;;
val m : string StringMap.t = <abstr>
# StringMap.find "John Doe" m;;
- : string = "555-1212"
Note that in order to use Lists of pairs and functional maps both provide a purely functional interface. By contrast, hash tables provide an imperative interface. For many operations, hash tables are significantly faster than lists of pairs and functional maps. OptimJ
The OptimJ programming language is an extension of Java 5. As does Java, Optimj provides maps; but OptimJ also provides true associative arrays. Java arrays are indexed with non-negative integers; associative arrays are indexed with any type of key. String[String] phoneBook = {
"Sally Smart" -> "555-9999",
"John Doe" -> "555-1212",
"J. Random Hacker" -> "553-1337"
};
// String[String] is not a java type but an optimj type:
// associative array of strings indexed by strings.
// iterate over the values
for (String number : phoneBook) {
System.out.println(number);
}
// The previous statement prints: "555-9999" "555-1212" "553-1337"
// 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"
Of course, it is possible to define multi-dimensional arrays, to mix Java arrays and associative arrays, to mix maps and associative arrays. int[String][][double] a;
java.util.Map<String[Object], Integer> b;
Perl 5Perl 5 has built-in, language-level support for associative arrays. Modern Perl 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 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 my %phone_book = (
'Sally Smart' => '555-9999',
'John Doe' => '555-1212',
'J. Random Hacker' => '553-1337',
);
Accessing a hash element uses the syntax The list of keys and values can be extracted using the built-in functions foreach $name (keys %phone_book) {
print $name, "\n";
}
One can iterate through (key, value) pairs using the while (($name, $number) = each %phone_book) {
print 'Number for ', $name, ': ', $number, "\n";
}
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',
'John Doe' => '555-1212',
'J. Random Hacker' => '553-1337',
};
Values in a hash reference are accessed using the dereferencing operator: print $phone_book->{'Sally Smart'};
When the hash contained in the hash reference needs to be referred to as a whole, as with the foreach $name (keys %{$phone_book}) {
print 'Number for ', $name, ': ', $phone_book->{$name}, "\n";
}
Perl 6 (Raku)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" role. As in 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 my %phone-book =
'Sally Smart' => '555-9999',
'John Doe' => '555-1212',
'J. Random Hacker' => '553-1337',
;
Accessing a hash element uses the syntax The list of keys and values can be extracted using the built-in functions for %phone-book.keys -> $name {
say $name;
}
By default, when iterating through a hash, one gets key–value pairs. for %phone-book -> $entry {
say "Number for $entry.key(): $entry.value()"; # using extended interpolation features
}
It is also possible to get alternating key values and value values by using the for %phone-book.kv -> $name, $number {
say "Number for $name: $number";
}
Raku doesn't have any references. Hashes can be passed as single parameters that are not 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 {
say "Number for $name: $number";
}
}
list-phone-book(%phone-book);
In compliance with gradual typing, hashes may be subjected to type constraints, confining a set of valid keys to a certain type. # Define a hash whose keys may only be integer numbers ("Int" type).
my %numbersWithNames{Int};
# Keys must be integer numbers, as in this case.
%numbersWithNames.push(1 => "one");
# This will cause an error, as strings as keys are invalid.
%numbersWithNames.push("key" => "two");
PHPPHP's built-in array type is, in reality, an associative array. Even when using numerical indexes, PHP internally stores arrays as associative arrays.[13] So, PHP can have non-consecutively numerically indexed arrays. The keys have to be of integer (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: $phonebook = array();
$phonebook['Sally Smart'] = '555-9999';
$phonebook['John Doe'] = '555-1212';
$phonebook['J. Random Hacker'] = '555-1337';
// or
$phonebook = array(
'Sally Smart' => '555-9999',
'John Doe' => '555-1212',
'J. Random Hacker' => '555-1337',
);
// or, as of PHP 5.4
$phonebook = [
'Sally Smart' => '555-9999',
'John Doe' => '555-1212',
'J. Random Hacker' => '555-1337',
];
// or
$phonebook['contacts']['Sally Smart']['number'] = '555-9999';
$phonebook['contacts']['John Doe']['number'] = '555-1212';
$phonebook['contacts']['J. Random Hacker']['number'] = '555-1337';
PHP can loop through an associative array as follows: 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";
}
PHP has an extensive set of functions to operate on arrays.[14] Associative arrays that can use objects as keys, instead of strings and integers, can be implemented with the PikePike 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",
"John Doe":"555-1212",
"J. Random Hacker":"555-1337"
]);
Accessing and testing for presence in mappings is done using the indexing operator. So Iterating through a mapping can be done using foreach(phonebook; string key; string value) {
write("%s:%s\n", key, value);
}
Or using an iterator object: Mapping.Iterator i = get_iterator(phonebook);
while (i->index()) {
write("%s:%s\n", i->index(), i->value());
i->next();
}
Elements of a mapping can be removed using string sallys_number = m_delete(phonebook, "Sally Smart");
PostScriptIn PostScript, associative arrays are called dictionaries. In Level 1 PostScript they must be created explicitly, but Level 2 introduced direct declaration using a double-angled-bracket syntax: % Level 1 declaration
3 dict dup begin
/red (rouge) def
/green (vert) def
/blue (bleu) def
end
% Level 2 declaration
<<
/red (rot)
/green (gruen)
/blue (blau)
>>
% Both methods leave the dictionary on the operand stack
Dictionaries can be accessed directly, using % With the previous two dictionaries still on the operand stack
/red get print % outputs 'rot'
begin
green print % outputs 'vert'
end
Dictionary contents can be iterated through using % Level 2 example
<<
/This 1
/That 2
/Other 3
>> {exch =print ( is ) print ==} forall
Which may output: That is 2
This is 1
Other is 3
Dictionaries can be augmented (up to their defined size only in Level 1) or altered using % define a dictionary for easy reuse:
/MyDict <<
/rouge (red)
/vert (gruen)
>> def
% add to it
MyDict /bleu (blue) put
% change it
MyDict /vert (green) put
% remove something
MyDict /rouge undef
PrologSome versions of Prolog include dictionary ("dict") utilities.[16] PythonIn Python, associative arrays are called "dictionaries". Dictionary literals are delimited by curly braces: phonebook = {
"Sally Smart": "555-9999",
"John Doe": "555-1212",
"J. Random Hacker": "553-1337",
}
Dictionary items can be accessed using the array indexing operator: >>> phonebook["Sally Smart"]
'555-9999'
Loop iterating through all the keys of the dictionary: >>> for key in phonebook:
... print(key, phonebook[key])
Sally Smart 555-9999
J. Random Hacker 553-1337
John Doe 555-1212
Iterating through (key, value) tuples: >>> for key, value in phonebook.items():
... print(key, value)
Sally Smart 555-9999
J. Random Hacker 553-1337
John Doe 555-1212
Dictionary keys can be individually deleted using the >>> del phonebook["John Doe"]
>>> val = phonebook.pop("Sally Smart")
>>> phonebook.keys() # Only one key left
['J. Random Hacker']
Python 2.7 and 3.x also support dict comprehensions (similar to list comprehensions), a compact syntax for generating a dictionary from any iterator: >>> 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'}
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",
"John Doe": None,
"J. Random Hacker": -3.32,
14: "555-3322",
}
The dictionary keys must be of an immutable data type. In Python, strings are immutable due to their method of implementation. RedIn Red the built-in A map can be written as a literal, such as Red [Title:"My map"]
my-map: make map! [
"Sally Smart" "555-9999"
"John Doe" "555-1212"
"J. Random Hacker" "553-1337"
]
; 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.
my-other-map: make map! [foo: 42 bar: false]
; 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]]
; or keys can be added after creation:
my-other-map: make map! [foo: 42]
my-other-map/bar: false
; 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
; You can also loop through all keys and values with <code>foreach</code>:
foreach [key value] my-map [
print [key "is associated to" value]
]
; A key can be removed using <code>remove/key</code>:
remove/key my-map "Sally Smart"
REXXIn REXX, associative arrays are called "stem variables" or "Compound variables". KEY = 'Sally Smart'
PHONEBOOK.KEY = '555-9999'
KEY = 'John Doe'
PHONEBOOK.KEY = '555-1212'
KEY = 'J. Random Hacker'
PHONEBOOK.KEY = '553-1337'
Stem variables with numeric keys typically start at 1 and go up from there. The 0-key stem variable by convention contains the total number of items in the stem: NAME.1 = 'Sally Smart'
NAME.2 = 'John Doe'
NAME.3 = 'J. Random Hacker'
NAME.0 = 3
REXX has no easy way of automatically accessing the keys of a stem variable; and typically the keys are stored in a separate associative array, with numeric keys. RubyIn Ruby a hash table is used as follows: phonebook = {
'Sally Smart' => '555-9999',
'John Doe' => '555-1212',
'J. Random Hacker' => '553-1337'
}
phonebook['John Doe']
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}
Sally Smart => 555-9999
John Doe => 555-1212
J. Random Hacker => 553-1337
=> {"Sally Smart"=>"555-9999", "John Doe"=>"555-1212", "J. Random Hacker"=>"553-1337"}
irb(main):009:0> ### iterate keys only
irb(main):010:0* phonebook.each_key {|key| puts key}
Sally Smart
John Doe
J. Random Hacker
=> {"Sally Smart"=>"555-9999", "John Doe"=>"555-1212", "J. Random Hacker"=>"553-1337"}
irb(main):011:0> ### iterate values only
irb(main):012:0* phonebook.each_value {|value| puts value}
555-9999
555-1212
553-1337
=> {"Sally Smart"=>"555-9999", "John Doe"=>"555-1212", "J. Random Hacker"=>"553-1337"}
Ruby 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. RustThe Rust standard library provides a hash map ( 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");
The default iterators visit all entries as tuples. The for (name, number) in &phone_book {
println!("{} {}", name, number);
}
There is also an iterator for keys: for name in phone_book.keys() {
println!("{}", name);
}
S-LangS-Lang has an associative array type: phonebook = Assoc_Type[];
phonebook["Sally Smart"] = "555-9999"
phonebook["John Doe"] = "555-1212"
phonebook["J. Random Hacker"] = "555-1337"
You can also loop through an associated array in a number of ways: foreach name (phonebook) {
vmessage ("%s %s", name, phonebook[name]);
}
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]);
ScalaScala provides an immutable val phonebook = Map("Sally Smart" -> "555-9999",
"John Doe" -> "555-1212",
"J. Random Hacker" -> "553-1337")
Scala's type inference will decide that this is a phonebook.get("Sally Smart")
This returns an SmalltalkIn Smalltalk a 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'.
To access an entry the message phonebook at: 'Sally Smart'
Which gives: '555-9999'
A dictionary hashes, or compares, based on equality and marks both key and value as strong references. Variants exist in which hash/compare on identity (IdentityDictionary) or keep weak references (WeakKeyDictionary / WeakValueDictionary). Because every object implements #hash, any object can be used as key (and of course also as value). SNOBOLSNOBOL is one of the first (if not the first) programming languages to use associative arrays. 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'
Standard MLThe 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"), - structure StringMap = BinaryMapFn (struct
type ord_key = string
val compare = String.compare
end);
structure StringMap : ORD_MAP
- val m = StringMap.insert (StringMap.empty, "Sally Smart", "555-9999")
val m = StringMap.insert (m, "John Doe", "555-1212")
val m = StringMap.insert (m, "J. Random Hacker", "553-1337");
val m =
T
{cnt=3,key="John Doe",
left=T {cnt=1,key="J. Random Hacker",left=E,right=E,value="553-1337"},
right=T {cnt=1,key="Sally Smart",left=E,right=E,value="555-9999"},
value="555-1212"} : string StringMap.map
- StringMap.find (m, "John Doe");
val it = SOME "555-1212" : string option
SML/NJ also provides a polymorphic hash table: - exception NotFound;
exception NotFound
- val m : (string, string) HashTable.hash_table = HashTable.mkTable (HashString.hashString, op=) (3, NotFound);
val m =
HT
{eq_pred=fn,hash_fn=fn,n_items=ref 0,not_found=NotFound(-),
table=ref [|NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,...|]}
: (string,string) HashTable.hash_table
- HashTable.insert m ("Sally Smart", "555-9999");
val it = () : unit
- HashTable.insert m ("John Doe", "555-1212");
val it = () : unit
- HashTable.insert m ("J. Random Hacker", "553-1337");
val it = () : unit
HashTable.find m "John Doe"; (* returns NONE if not found *)
val it = SOME "555-1212" : string option
- HashTable.lookup m "John Doe"; (* raises the exception if not found *)
val it = "555-1212" : string
Monomorphic hash tables are also supported, using the Another Standard ML implementation, Moscow ML, also provides some associative containers. First, it provides polymorphic hash tables in the TclThere 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. arrayset {phonebook(Sally Smart)} 555-9999
set john {John Doe}
set phonebook($john) 555-1212
set {phonebook(J. Random Hacker)} 553-1337
If there is a space character in the variable name, the name must be grouped using either curly brackets (no substitution performed) or double quotes (substitution is performed). Alternatively, several array elements can be set by a single command, by presenting 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]
To access one array entry and put it to standard output: puts $phonebook(Sally\ Smart)
Which returns this result: 555-9999
To retrieve the entire array as a dictionary: array get phonebook
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
dictset phonebook [dict create {Sally Smart} 555-9999 {John Doe} 555-1212 {J. Random Hacker} 553-1337]
To look up an item: dict get $phonebook {John Doe}
To iterate through a dict: foreach {name number} $phonebook {
puts "name: $name\nnumber: $number"
}
Visual BasicVisual Basic can use the Dictionary class from the Microsoft Scripting Runtime (which is shipped with Visual Basic 6). There is no standard implementation common to all versions: ' Requires a reference to SCRRUN.DLL in Project Properties
Dim phoneBook As New Dictionary
phoneBook.Add "Sally Smart", "555-9999"
phoneBook.Item("John Doe") = "555-1212"
phoneBook("J. Random Hacker") = "553-1337"
For Each name In phoneBook
MsgBox name & " = " & phoneBook(name)
Next
Visual Basic .NETVisual Basic .NET uses the collection classes provided by the .NET Framework. CreationThe following code demonstrates the creation and population of a dictionary (see 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"
An alternate syntax would be to use a collection initializer, which compiles down to individual calls to Dim dic As New System.Collections.Dictionary(Of String, String) From {
{"Sally Smart", "555-9999"},
{"John Doe", "555-1212"},
{"J. Random Hacker", "553-1337"}
}
Access by keyExample demonstrating access (see C# access): Dim sallyNumber = dic("Sally Smart")
' or
Dim sallyNumber = dic.Item("Sally Smart")
Dim result As String = Nothing
Dim sallyNumber = If(dic.TryGetValue("Sally Smart", result), result, "n/a")
EnumerationExample demonstrating enumeration (see #C# enumeration): ' 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
Windows PowerShellUnlike many other command line interpreters, Windows PowerShell has built-in, language-level support for defining associative arrays: $phonebook = @{
'Sally Smart' = '555-9999';
'John Doe' = '555-1212';
'J. Random Hacker' = '553-1337'
}
As in JavaScript, if the property name is a valid identifier, the quotes can be omitted: $myOtherObject = @{ foo = 42; bar = $false }
Entries can be separated by either a semicolon or a newline: $myOtherObject = @{ foo = 42
bar = $false ;
zaz = 3
}
Keys and values can be any .NET object type: $now = [DateTime]::Now
$tomorrow = $now.AddDays(1)
$ProcessDeletionSchedule = @{
(Get-Process notepad) = $now
(Get-Process calc) = $tomorrow
}
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' }
New entries can also be added by using the array index operator, the property operator, or the $phonebook = @{}
$phonebook['Sally Smart'] = '555-9999'
$phonebook.'John Doe' = '555-1212'
$phonebook.Add('J. Random Hacker', '553-1337')
To dereference assigned objects, the array index operator, the property operator, or the parameterized property $phonebook['Sally Smart']
$phonebook.'John Doe'
$phonebook.Item('J. Random Hacker')
You can loop through an associative array as follows: $phonebook.Keys | foreach { "Number for {0}: {1}" -f $_,$phonebook.$_ }
An entry can be removed using the $phonebook.Remove('Sally Smart')
Hash tables can be added: $hash1 = @{ a=1; b=2 }
$hash2 = @{ c=3; d=4 }
$hash3 = $hash1 + $hash2
Data serialization formats support
Many data serialization formats also support associative arrays (see this table) JSONIn JSON, associative arrays are also referred to as objects. Keys can only be strings. {
"Sally Smart": "555-9999",
"John Doe": "555-1212",
"J. Random Hacker": "555-1337"
}
YAMLYAML 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. Sally Smart: 555-9999
John Doe: 555-1212
J. Random Hacker: 555-1337
References
|
Portal di Ensiklopedia Dunia