Associative array/Creation
You are encouraged to solve this task according to the task description, using any language you may know.
- Task
The goal is to create an associative array (also known as a dictionary, map, or hash).
Related tasks:
- See also
- Array
- Associative array: Creation, Iteration
- Collections
- Compound data type
- Doubly-linked list: Definition, Element definition, Element insertion, List Traversal, Element Removal
- Linked list
- Queue: Definition, Usage
- Set
- Singly-linked list: Element definition, Element insertion, List Traversal, Element Removal
- Stack
ActionScript
Because ActionScript does not have associative arrays in the normal sense, Object objects are used instead and keys are simply properties on those objects. <lang actionscript>var map:Object = {key1: "value1", key2: "value2"}; trace(map['key1']); // outputs "value1"
// Dot notation can also be used trace(map.key2); // outputs "value2"
// More keys and values can then be added map['key3'] = "value3"; trace(map['key3']); // outputs "value3"</lang> Note: The Object only supports String keys. To use an object as a key, try the flash.utils.Dictionary class.
Ada
<lang ada>with Ada.Containers.Ordered_Maps; with Ada.Strings.Unbounded; use Ada.Strings.Unbounded; with Ada.Text_IO;
procedure Associative_Array is
-- Instantiate the generic package Ada.Containers.Ordered_Maps
package Associative_Int is new Ada.Containers.Ordered_Maps(Unbounded_String, Integer); use Associative_Int; Color_Map : Map; Color_Cursor : Cursor; Success : Boolean; Value : Integer;
begin
-- Add values to the ordered map
Color_Map.Insert(To_Unbounded_String("Red"), 10, Color_Cursor, Success); Color_Map.Insert(To_Unbounded_String("Blue"), 20, Color_Cursor, Success); Color_Map.Insert(To_Unbounded_String("Yellow"), 5, Color_Cursor, Success);
-- retrieve values from the ordered map and print the value and key -- to the screen
Value := Color_Map.Element(To_Unbounded_String("Red")); Ada.Text_Io.Put_Line("Red:" & Integer'Image(Value)); Value := Color_Map.Element(To_Unbounded_String("Blue")); Ada.Text_IO.Put_Line("Blue:" & Integer'Image(Value)); Value := Color_Map.Element(To_Unbounded_String("Yellow")); Ada.Text_IO.Put_Line("Yellow:" & Integer'Image(Value));
end Associative_Array;</lang>
Aikido
Aikido provides a native map for associative arrays. You can create them using a map literal and you can insert and remove items on the fly. <lang aikido> var names = {} // empty map names["foo"] = "bar" names[3] = 4
// initialized map var names2 = {"foo": bar, 3:4}
// lookup map var name = names["foo"] if (typeof(name) == "none") {
println ("not found")
} else {
println (name)
}
// remove from map delete names["foo"]
</lang>
Aime
Aime records are heterogenous associative arrays. No creation procedure is required, declaration is fine. <lang aime>record r;</lang> <lang aime>r_put(r, "A", 33); # an integer value r_put(r, "C", 2.5); # a real value r_put(r, "B", "associative"); # a string value</lang>
ALGOL 68
<lang algol68>main:(
MODE COLOR = BITS; FORMAT color repr = $"16r"16r6d$;
# This is an associative array which maps strings to ints # MODE ITEM = STRUCT(STRING key, COLOR value); REF[]ITEM color map items := LOC[0]ITEM;
PROC color map find = (STRING color)REF COLOR:( REF COLOR out;
- linear search! #
FOR index FROM LWB key OF color map items TO UPB key OF color map items DO IF color = key OF color map items[index] THEN out := value OF color map items[index]; GO TO found FI OD; NIL EXIT found: out );
PROC color map = (STRING color)REF COLOR:( REF COLOR out = color map find(color); IF out :=: REF COLOR(NIL) THEN # extend color map array # HEAP[UPB key OF color map items + 1]ITEM color map append; color map append[:UPB key OF color map items] := color map items; color map items := color map append; value OF (color map items[UPB value OF color map items] := (color, 16r000000)) # black # ELSE out FI ); # First, populate it with some values # color map("red") := 16rff0000; color map("green") := 16r00ff00; color map("blue") := 16r0000ff; color map("my favourite color") := 16r00ffff; # then, get some values out # COLOR color := color map("green"); # color gets 16r00ff00 # color := color map("black"); # accessing unassigned values assigns them to 16r0 # # get some value out without accidentally inserting new ones # REF COLOR value = color map find("green"); IF value :=: REF COLOR(NIL) THEN put(stand error, ("color not found!", new line)) ELSE printf(($"green: "f(color repr)l$, value)) FI; # Now I changed my mind about my favourite color, so change it # color map("my favourite color") := 16r337733; # print out all defined colors # FOR index FROM LWB color map items TO UPB color map items DO ITEM item = color map items[index]; putf(stand error, ($"color map("""g""") = "f(color repr)l$, item)) OD;
FORMAT fmt; FORMAT comma sep = $"("n(UPB color map items-1)(f(fmt)", ")f(fmt)")"$;
fmt := $""""g""""$; printf(($g$,"keys: ", comma sep, key OF color map items, $l$)); fmt := color repr; printf(($g$,"values: ", comma sep, value OF color map items, $l$))
)</lang>
- Output:
green: 16r00ff00 color map("red") = 16rff0000 color map("green") = 16r00ff00 color map("blue") = 16r0000ff color map("my favourite color") = 16r337733 color map("black") = 16r000000 keys: ("red", "green", "blue", "my favourite color", "black") values: (16rff0000, 16r00ff00, 16r0000ff, 16r337733, 16r000000)
Apex
Apex provides a Map datatype that maps unique keys to a single value. Both keys and values can be any data type, including user-defined types. Like Java, equals and hashCode are used to determine key uniqueness for user-defined types. Uniqueness of sObject keys is determined by comparing field values.
Creating a new empty map of String to String: <lang apex>// Cannot / Do not need to instantiate the algorithm implementation (e.g, HashMap). Map<String, String> strMap = new Map<String, String>(); strMap.put('a', 'aval'); strMap.put('b', 'bval');
System.assert( strMap.containsKey('a') ); System.assertEquals( 'bval', strMap.get('b') ); // String keys are case-sensitive System.assert( !strMap.containsKey('A') );</lang>
Creating a new map of String to String with values initialized: <lang apex>Map<String, String> strMap = new Map<String, String>{
'a' => 'aval', 'b' => 'bval'
};
System.assert( strMap.containsKey('a') ); System.assertEquals( 'bval', strMap.get('b') );</lang>
APL
<lang apl>⍝ Create a namespace ("hash")
X←⎕NS ⍬ ⍝ Assign some names X.this←'that' X.foo←88 ⍝ Access the names X.this
that
⍝ Or do it the array way X.(foo this)
88 that
⍝ Namespaces are first class objects sales ← ⎕NS ⍬ sales.(prices quantities) ← (100 98.4 103.4 110.16) (10 12 8 10) sales.(revenue ← prices +.× quantities) sales.revenue
4109.6</lang>
App Inventor
Associative arrays in App Inventor are lists of key:value 'pairs'.
When a list is organized as pairs, the lookup in pairs block can be used to retrieve an associated value from a key name.
<VIEW BLOCKS AND ANDROID APP>
AutoHotkey
True arrays
AutoHotkey_L has Objects which function as associative arrays. <lang AutoHotkey>associative_array := {key1: "value 1", "Key with spaces and non-alphanumeric characters !*+": 23} MsgBox % associative_array.key1 . "`n" associative_array["Key with spaces and non-alphanumeric characters !*+"]</lang>
Legacy versions
AutoHotkey_Basic does not have typical arrays. However, variable names can be concatenated, simulating associative arrays. <lang AutoHotkey>arrayX1 = first arrayX2 = second arrayX3 = foo arrayX4 = bar Loop, 4
Msgbox % arrayX%A_Index%</lang>
AWK
Arrays in AWK are indeed associative arrays. <lang awk>BEGIN {
a["red"] = 0xff0000 a["green"] = 0x00ff00 a["blue"] = 0x0000ff for (i in a) { printf "%8s %06x\n", i, a[i] } # deleting a key/value delete a["red"] for (i in a) { print i } # check if a key exists print ( "red" in a ) # print 0 print ( "blue" in a ) # print 1
}</lang>
Babel
<lang babel>
(("foo" 13) ("bar" 42) ("baz" 77)) ls2map !</lang>
BASIC256
<lang BASIC256>global values$, keys$ dim values$[1] dim keys$[1]
call updateKey("a","apple") call updateKey("b","banana") call updateKey("c","cucumber")
gosub show
print "I like to eat a " + getValue$("c") + " on my salad."
call deleteKey("b") call updateKey("c","carrot") call updateKey("e","endive") gosub show
end
show: for t = 0 to countKeys()-1
print getKeyByIndex$(t) + " " + getValueByIndex$(t)
next t print return
subroutine updateKey(key$, value$)
# update or add an item i=findKey(key$) if i=-1 then i = freeKey() keys$[i] = key$ end if values$[i] = value$
end subroutine
subroutine deleteKey(key$)
# delete by clearing the key i=findKey(key$) if i<>-1 then keys$[i] = "" end if
end subroutine
function freeKey()
# find index of a free element in the array for n = 0 to keys$[?]-1 if keys$[n]="" then return n next n redim keys$[n+1] redim values$[n+1] return n
end function
function findKey(key$)
# return index or -1 if not found for n = 0 to keys$[?]-1 if key$=keys$[n] then return n next n return -1
end function
function getValue$(key$)
# return a value by the key or "" if not existing i=findKey(key$) if i=-1 then return "" end if return values$[i]
end function
function countKeys()
# return number of items # remember to skip the empty keys (deleted ones) k = 0 for n = 0 to keys$[?] -1 if keys$[n]<>"" then k++ next n return k
end function
function getValueByIndex$(i)
# get a value by the index # remember to skip the empty keys (deleted ones) k = 0 for n = 0 to keys$[?] -1 if keys$[n]<>"" then if k=i then return values$[k] k++ endif next n return ""
end function
function getKeyByIndex$(i)
# get a key by the index # remember to skip the empty keys (deleted ones) k = 0 for n = 0 to keys$[?] -1 if keys$[n]<>"" then if k=i then return keys$[k] k++ endif next n return ""
end function</lang>
- Output:
a apple b banana c cucumber I like to eat a cucumber on my salad. a apple e endive c carrot
Batch File
This is cheating, I'm sure of it.
<lang dos>::assocarrays.cmd @echo off setlocal ENABLEDELAYEDEXPANSION set array.dog=1 set array.cat=2 set array.wolf=3 set array.cow=4 for %%i in (dog cat wolf cow) do call :showit array.%%i !array.%%i! set c=-27 call :mkarray sicko flu 5 measles 6 mumps 7 bromodrosis 8 for %%i in (flu measles mumps bromodrosis) do call :showit "sicko^&%%i" !sicko^&%%i! endlocal goto :eof
- mkarray
set %1^&%2=%3 shift /2 shift /2 if "%2" neq "" goto :mkarray goto :eof
- showit
echo %1 = %2 goto :eof </lang>
- Output:
array.dog = 1 array.cat = 2 array.wolf = 3 array.cow = 4 "sicko&flu" = 5 "sicko&measles" = 6 "sicko&mumps" = 7 "sicko&bromodrosis" = 8
BBC BASIC
<lang bbcbasic> REM Store some values with their keys:
PROCputdict(mydict$, "FF0000", "red") PROCputdict(mydict$, "00FF00", "green") PROCputdict(mydict$, "0000FF", "blue") REM Retrieve some values using their keys: PRINT FNgetdict(mydict$, "green") PRINT FNgetdict(mydict$, "red") END DEF PROCputdict(RETURN dict$, value$, key$) IF dict$ = "" dict$ = CHR$(0) dict$ += key$ + CHR$(1) + value$ + CHR$(0) ENDPROC DEF FNgetdict(dict$, key$) LOCAL I%, J% I% = INSTR(dict$, CHR$(0) + key$ + CHR$(1)) IF I% = 0 THEN = "" ELSE I% += LEN(key$) + 2 J% = INSTR(dict$, CHR$(0), I%) = MID$(dict$, I%, J% - I%)</lang>
Bracmat
The hash is the only built-in Bracmat class. It is best used for e.g. a large dictionary, when manipulation of a very long list of key/value pairs with pattern matching would become too CPU-intensive. The same key can be stored with different values, as the example shows. If that is not desirable, the key (and its value) should be removed first. <lang bracmat> new$hash:?myhash & (myhash..insert)$(title."Some title") & (myhash..insert)$(formula.a+b+x^7) & (myhash..insert)$(fruit.apples oranges kiwis) & (myhash..insert)$(meat.) & (myhash..insert)$(fruit.melons bananas) & out$(myhash..find)$fruit & (myhash..remove)$formula & (myhash..insert)$(formula.x^2+y^2) & out$(myhash..find)$formula;</lang>
- Output:
(fruit.melons bananas) (fruit.apples oranges kiwis) formula.x^2+y^2
Brat
<lang brat>h = [:] #Empty hash
h[:a] = 1 #Assign value h[:b] = [1 2 3] #Assign another value
h2 = [a: 1, b: [1 2 3], 10 : "ten"] #Initialized hash
h2[:b][2] #Returns 3</lang>
C
Solution is at Associative arrays/Creation/C.
C++
The C++ standard defines std::map as a means of creating an association between a key of one arbitrary type and a value of another arbitrary type. This requires the inclusion of the standard header map.
<lang cpp>#include <map></lang>
Creation
To create a simple map whose key is of type A and whose value is of type B, one would define the variable like so: <lang cpp>std::map<A, B> exampleMap</lang>
If one wanted to us a key type of int and a value of double, you would define it like so:
<lang cpp>std::map<int, double> exampleMap</lang>
Insertion
Once we've created our map, we've got a couple different ways to insert the value. Let's use an example key of 7, and an exable value of 3.14.
Operator[]
The first method is using the [] operator. <lang cpp>exampleMap[7] = 3.14</lang>
Of course, you can use a variable (or any rvalue of the correct type) for the key or value parameters: <lang cpp>int myKey = 7; double myValue = 3.14; exampleMap[myKey] = myValue;</lang>
insert()
The second approach is a little more complicated. We have to use the pair<> template: <lang cpp>exampleMap.insert(std::pair<int, double>(7,3.14));</lang> or by using make_pair to avoid repeating key/value types: <lang cpp>exampleMap.insert(std::make_pair(7,3.14));</lang>
Lookup
As with insertion, there are a couple ways we can retrieve the value.
operator[]
We use it as an rvalue, supplying the correct key: <lang cpp>myValue = exampleMap[myKey]</lang> If the value doesn't already exist, a default-constructed object of the value's type will be inserted using the key you specified, and that default value will be returned.
find()
Alternatively, you can look up a value by using find(), storing its return value in an iterator, and comparing the iterator against the map's end() sentinal value: <lang cpp>double myValue = 0.0; std::map<int, double>::iterator myIterator = exampleMap.find(myKey); if(exampleMap.end() != myIterator) {
// Return the value for that key. myValue = myIterator->second;
}</lang>
The need for the ->second code is because our iterator points to a pair<>(), and our value is the second member of that pair.
This code assigns a 0 to myValue if the map contained a value.
Example
This simple program creates a map, assigns a value to that map, retrieves a value from that map, and prints the value to STDOUT. <lang cpp>#include <map>
- include <iostreams>
int main() {
// Create the map. std::map<int, double> exampleMap;
// Choose our key int myKey = 7;
// Choose our value double myValue = 3.14;
// Assign a value to the map with the specified key. exampleMap[myKey] = myValue;
// Retrieve the value double myRetrievedValue = exampleMap[myKey];
// Display our retrieved value. std::cout << myRetrievedValue << std::endl;
// main() must return 0 on success. return 0;
}</lang>
C#
Platform: .NET 1.x <lang csharp>System.Collections.HashTable map = new System.Collections.HashTable(); map["key1"] = "foo";</lang>
Platform: .NET 2.0 <lang csharp>Dictionary<string, string> map = new Dictionary<string,string>(); map[ "key1" ] = "foo";</lang>
<lang csharp>var map = new Dictionary<string, string> Template:"key1", "foo";</lang>
Ceylon
<lang ceylon>import ceylon.collection {
ArrayList, HashMap, naturalOrderTreeMap }
shared void run() {
// the easiest way is to use the map function to create // an immutable map value myMap = map { "foo" -> 5, "bar" -> 10, "baz" -> 15, "foo" -> 6 // by default the first "foo" will remain };
// or you can use the HashMap constructor to create // a mutable one value myOtherMap = HashMap { "foo"->"bar" }; myOtherMap.put("baz", "baxx");
// there's also a sorted red/black tree map value myTreeMap = naturalOrderTreeMap { 1 -> "won", 2 -> "too", 4 -> "fore" }; for(num->homophone in myTreeMap) { print("``num`` is ``homophone``"); }
}</lang>
Chapel
In Chapel, associative arrays are regular arrays with a non-integer domain - values used as keys into the array. The creation of the domain is independent from the creation of the array, and in fact the same domain can be used for multiple arrays, creating associative arrays with identical sets of keys. When the domain is changed, all arrays that use it will be reallocated.
<lang>// arr is an array of string to int. any type can be used in both places. var keys: domain(string); var arr: [keys] int;
// keys can be added to a domain using +, new values will be initialized to the default value (0 for int) keys += "foo"; keys += "bar"; keys += "baz";
// array access via [] or () arr["foo"] = 1; arr["bar"] = 4; arr("baz") = 6;
// write auto-formats domains and arrays writeln("Keys: ", keys); writeln("Values: ", arr);
// keys can be deleted using - keys -= "bar";
writeln("Keys: ", keys); writeln("Values: ", arr);
// chapel also supports array literals var arr2 = [ "John" => 3, "Pete" => 14 ];
writeln("arr2 keys: ", arr2.domain); writeln("arr2 values: ", arr2);</lang>
- Output:
Keys: {foo, bar, baz} Values: 1 4 6 Keys: {foo, baz} Values: 1 6 arr2 keys: {John, Pete} arr2 values: 3 14
Clojure
<lang lisp>{:key "value"
:key2 "value2" :key3 "value3"}</lang>
ColdFusion
<lang cfm><cfset myHash = structNew()> <cfset myHash.key1 = "foo"> <cfset myHash["key2"] = "bar"> <cfset myHash.put("key3","java-style")></lang>
In ColdFusion, a map is literally a java.util.HashMap, thus the above 3rd method is possible.
Common Lisp
<lang lisp>;; default :test is #'eql, which is suitable for numbers only,
- or for implementation identity for other types!
- Use #'equalp if you want case-insensitive keying on strings.
(setf my-hash (make-hash-table :test #'equal)) (setf (gethash "H2O" my-hash) "Water") (setf (gethash "HCl" my-hash) "Hydrochloric Acid") (setf (gethash "CO" my-hash) "Carbon Monoxide")
- That was actually a hash table, an associative array or
- alist is written like this
(defparameter *legs* '((cow . 4) (flamingo . 2) (centipede . 100)))
- you can use assoc to do lookups and cons new elements onto it to make it longer.</lang>
Component Pascal
BlackBox Componente Builder
Using a handmade collections module with the following interface
<lang oberon2>
DEFINITION Collections;
IMPORT Boxes;
CONST notFound = -1;
TYPE Hash = POINTER TO RECORD cap-, size-: INTEGER; (h: Hash) ContainsKey (k: Boxes.Object): BOOLEAN, NEW; (h: Hash) Get (k: Boxes.Object): Boxes.Object, NEW; (h: Hash) IsEmpty (): BOOLEAN, NEW; (h: Hash) Put (k, v: Boxes.Object): Boxes.Object, NEW; (h: Hash) Remove (k: Boxes.Object): Boxes.Object, NEW; (h: Hash) Reset, NEW END;
HashMap = POINTER TO RECORD cap-, size-: INTEGER; (hm: HashMap) ContainsKey (k: Boxes.Object): BOOLEAN, NEW; (hm: HashMap) ContainsValue (v: Boxes.Object): BOOLEAN, NEW; (hm: HashMap) Get (k: Boxes.Object): Boxes.Object, NEW; (hm: HashMap) IsEmpty (): BOOLEAN, NEW; (hm: HashMap) Keys (): POINTER TO ARRAY OF Boxes.Object, NEW; (hm: HashMap) Put (k, v: Boxes.Object): Boxes.Object, NEW; (hm: HashMap) Remove (k: Boxes.Object): Boxes.Object, NEW; (hm: HashMap) Reset, NEW; (hm: HashMap) Values (): POINTER TO ARRAY OF Boxes.Object, NEW END;
LinkedList = POINTER TO RECORD first-, last-: Node; size-: INTEGER; (ll: LinkedList) Add (item: Boxes.Object), NEW; (ll: LinkedList) Append (item: Boxes.Object), NEW; (ll: LinkedList) AsString (): POINTER TO ARRAY OF CHAR, NEW; (ll: LinkedList) Contains (item: Boxes.Object): BOOLEAN, NEW; (ll: LinkedList) Get (at: INTEGER): Boxes.Object, NEW; (ll: LinkedList) IndexOf (item: Boxes.Object): INTEGER, NEW; (ll: LinkedList) Insert (at: INTEGER; item: Boxes.Object), NEW; (ll: LinkedList) IsEmpty (): BOOLEAN, NEW; (ll: LinkedList) Remove (item: Boxes.Object), NEW; (ll: LinkedList) RemoveAt (at: INTEGER), NEW; (ll: LinkedList) Reset, NEW; (ll: LinkedList) Set (at: INTEGER; item: Boxes.Object), NEW END;
Vector = POINTER TO RECORD size-, cap-: LONGINT; (v: Vector) Add (item: Boxes.Object), NEW; (v: Vector) AddAt (item: Boxes.Object; i: INTEGER), NEW; (v: Vector) Contains (o: Boxes.Object): BOOLEAN, NEW; (v: Vector) Get (i: LONGINT): Boxes.Object, NEW; (v: Vector) IndexOf (o: Boxes.Object): LONGINT, NEW; (v: Vector) Remove (o: Boxes.Object), NEW; (v: Vector) RemoveIndex (i: LONGINT): Boxes.Object, NEW; (v: Vector) Set (i: LONGINT; o: Boxes.Object): Boxes.Object, NEW; (v: Vector) Trim, NEW END;
PROCEDURE NewHash (cap: INTEGER): Hash; PROCEDURE NewHashMap (cap: INTEGER): HashMap; PROCEDURE NewLinkedList (): LinkedList; PROCEDURE NewVector (cap: INTEGER): Vector;
END Collections. </lang> The program: <lang oberon2> MODULE BbtAssociativeArrays; IMPORT StdLog, Collections, Boxes;
PROCEDURE Do*; VAR hm : Collections.HashMap; o : Boxes.Object; keys, values: POINTER TO ARRAY OF Boxes.Object; i: INTEGER;
BEGIN hm := Collections.NewHashMap(1009); o := hm.Put(Boxes.NewString("first"),Boxes.NewInteger(1)); o := hm.Put(Boxes.NewString("second"),Boxes.NewInteger(2)); o := hm.Put(Boxes.NewString("third"),Boxes.NewInteger(3)); o := hm.Put(Boxes.NewString("one"),Boxes.NewInteger(1));
StdLog.String("size: ");StdLog.Int(hm.size);StdLog.Ln;
END Do;
END BbtAssociativeArrays.
</lang>
Execute:^Q BbtAssociativeArrays.Do
- Output:
size: 4
D
<lang d>void main() {
auto hash = ["foo":42, "bar":100]; assert("foo" in hash);
}</lang>
Dao
<lang dao>m = { => } # empty ordered map, future inserted keys will be ordered h = { -> } # empty hash map, future inserted keys will not be ordered
m = { 'foo' => 42, 'bar' => 100 } # with ordered keys h = { 'foo' -> 42, 'bar' -> 100 } # with unordered keys</lang>
Delphi
<lang Delphi>program AssociativeArrayCreation;
{$APPTYPE CONSOLE}
uses Generics.Collections;
var
lDictionary: TDictionary<string, Integer>;
begin
lDictionary := TDictionary<string, Integer>.Create; try lDictionary.Add('foo', 5); lDictionary.Add('bar', 10); lDictionary.Add('baz', 15); lDictionary.AddOrSetValue('foo', 6); // replaces value if it exists finally lDictionary.Free; end;
end.</lang>
E
<lang e>[].asMap() # immutable, empty ["one" => 1, "two" => 2] # immutable, 2 mappings [].asMap().diverge() # mutable, empty ["one" => 2].diverge(String, float64) # mutable, initial contents,
# typed (coerces to float)</lang>
EchoLisp
<lang scheme> (lib 'hash) ;; needs hash.lib (define H (make-hash)) ;; new hash table
- keys may be symbols, numbers, strings ..
- values may be any lisp object
(hash-set H 'simon 'antoniette)
→ antoniette
(hash-set H 'antoinette 'albert)
→ albert
(hash-set H "Elvis" 42)
→ 42
(hash-ref H 'Elvis)
→ #f ;; not found. Elvis is not "Elvis"
(hash-ref H "Elvis")
→ 42
(hash-ref H 'simon)
→ antoniette
(hash-count H)
→ 3
</lang>
Elena
<lang elena>#define system.
- define system'collections.
// --- Program ---
- symbol program =
[
// 1. Create #var aMap := Dictionary new. aMap@"key" := "foox". aMap@"key" := "foo". aMap@"key2":= "foo2". aMap@"key3":= "foo3". aMap@"key4":= "foo4".
].</lang>
Elixir
<lang elixir>defmodule RC do
def test_create do IO.puts "< create Map.new >" m = Map.new #=> creates an empty Map m1 = Map.put(m,:foo,1) m2 = Map.put(m1,:bar,2) print_vals(m2) print_vals(%{m2 | foo: 3}) end defp print_vals(m) do IO.inspect m Enum.each(m, fn {k,v} -> IO.puts "#{inspect k} => #{v}" end) end
end
RC.test_create</lang>
- Output:
< create Map.new > %{bar: 2, foo: 1} :bar => 2 :foo => 1 %{bar: 2, foo: 3} :bar => 2 :foo => 3
Emacs Lisp
<lang Lisp>(setq my-table (make-hash-table)) (puthash 'key 'value my-table)</lang>
make-hash-table
compares keys with eql
by default. This suits symbols and numbers (including floating point). For string keys an equal
test can be used,
<lang Lisp>(setq my-table (make-hash-table :test 'equal)) (puthash "key" 123 my-table)</lang>
define-hash-table-test
can create other key comparison types.
Erlang
Erlang offers several associative array type data structures, this example uses the dictionary data structure. <lang erlang> -module(assoc). -compile([export_all]).
test_create() ->
D = dict:new(), D1 = dict:store(foo,1,D), D2 = dict:store(bar,2,D1), print_vals(D2), print_vals(dict:store(foo,3,D2)).
print_vals(D) ->
lists:foreach(fun (K) -> io:format("~p: ~b~n",[K,dict:fetch(K,D)]) end, dict:fetch_keys(D)).
</lang>
- Output:
32> assoc:test_create(). bar: 2 foo: 1 bar: 2 foo: 3 ok
F#
.NET 3.5 Generic Dictionary (mutable) <lang fsharp> let dic = System.Collections.Generic.Dictionary<string,string>() ;; dic.Add("key","val") ; dic.["key"] <- "new val" ; </lang> Functional dictionary (immutable) <lang fsharp> let d = [("key","val");("other key","other val")] |> Map.ofList let newd = d.Add("new key","new val")
let takeVal (d:Map<string,string>) =
match d.TryFind("key") with | Some(v) -> printfn "%s" v | None -> printfn "not found"
</lang>
Factor
Associative mappings follow the associative protocol. See the docs. Here's an example using a hashtable that can be run in the listener : <lang factor>H{ { "one" 1 } { "two" 2 } } { [ "one" swap at . ]
[ 2 swap value-at . ] [ "three" swap at . ] [ [ 3 "three" ] dip set-at ] [ "three" swap at . ] } cleave</lang>
Fantom
Associative arrays are called 'maps' in Fantom:
<lang fantom> class Main {
public static Void main () { // create a map which maps Ints to Strs, with given key-value pairs Int:Str map := [1:"alpha", 2:"beta", 3:"gamma"]
// create an empty map Map map2 := [:] // now add some numbers mapped to their doubles 10.times |Int i| { map2[i] = 2*i }
}
} </lang>
Forth
The Forth dictionary is normally only used for function and symbol definitions, but you can also define separate wordlists for holding functions or data. There is no special syntax in the language for this, but you can define your own. All of Forth's defining words are available for adding things to the wordlist, but CREATE is most generic.
<lang forth>: get ( key len table -- data ) \ 0 if not present
search-wordlist if >body @ else 0 then ;
- put ( data key len table -- )
>r 2dup r@ search-wordlist if r> drop nip nip >body ! else r> get-current >r set-current \ switch definition word lists nextname create , r> set-current then ; wordlist constant bar
5 s" alpha" bar put 9 s" beta" bar put 2 s" gamma" bar put s" alpha" bar get . \ 5 8 s" Alpha" bar put \ Forth dictionaries are normally case-insensitive s" alpha" bar get . \ 8</lang> This is not necessarily a good option in all Forths, as the dictionary may be implemented as a simple linked list (normally not a problem because the dictionary is only used for compiling and interactive interpretation). GNU Forth and many other hosted Forths use hash tables for the dictionary, so this is a fine choice. If you need case-sensitive keys, GNU Forth has table and table-find, replacing wordlist and search-wordlist, respectively.
(The use of nextname ( str len -- ) is a GNU Forth extension to create; there is no means in the ANS standard to use a string on the stack to create a dictionary entry.)
Hashtable for mapping strings to integer <lang forth>include ffl/hct.fs
\ Create a hash table 'table' in the dictionary with a starting size of 10
10 hct-create htable
\ Insert entries
5 s" foo" htable hct-insert
10 s" bar" htable hct-insert 15 s" baz" htable hct-insert
\ Get entry from the table
s" bar" htable hct-get [IF]
.( Value:) . cr
[ELSE]
.( Entry not present.) cr
[THEN]</lang>
Go
Allowable key types are those with == and != operators. This includes is boolean, numeric, string, pointer, channel, and interface types. It also includes structs and arrays containing only these types. Disallowed as map keys are all slice, function, and map types. <lang go>// declare a nil map variable, for maps from string to int var x map[string]int
// make an empty map x = make(map[string]int)
// make an empty map with an initial capacity x = make(map[string]int, 42)
// set a value x["foo"] = 3
// getting values y1 := x["bar"] // zero value returned if no map entry exists for the key y2, ok := x["bar"] // ok is a boolean, true if key exists in the map
// removing keys delete(x, "foo")
// make a map with a literal x = map[string]int{ "foo": 2, "bar": 42, "baz": -1, }</lang>
Groovy
Create an empty map and add values <lang groovy>map = [:] map[7] = 7 map['foo'] = 'foovalue' map.put('bar', 'barvalue') map.moo = 'moovalue'
assert 7 == map[7] assert 'foovalue' == map.foo assert 'barvalue' == map['bar'] assert 'moovalue' == map.get('moo')</lang>
Create a pre-populated map and verify values <lang groovy>map = [7:7, foo:'foovalue', bar:'barvalue', moo:'moovalue']
assert 7 == map[7] assert 'foovalue' == map.foo assert 'barvalue' == map['bar'] assert 'moovalue' == map.get('moo')</lang>
Harbour
Create an empty array and add values: <lang visualfoxpro>arr := { => } arr[ 10 ] := "Val_10" arr[ "foo" ] := "foovalue"</lang> Create and initialize array: <lang visualfoxpro>arr := hb_Hash( 10, "Val_10", "foo", "foovalue" ) // or arr := { 10 => "Val_10", "foo" => "foovalue" }</lang>
Haskell
Binary trees:
<lang haskell>import Data.Map
dict = fromList [("key1","val1"), ("key2","val2")]
ans = Data.Map.lookup "key2" dict -- evaluates to Just "val2" </lang>
It is also possible to use association lists (lists of pairs). It is inefficient (O(n) lookup), but simple. <lang haskell>dict = [("key1","val1"), ("key2","val2")]
ans = lookup "key2" dict -- evaluates to Just "val2" </lang>
GHC also had an imperative hash table implementation in the Data.HashTable
module, but was removed in GHC 7.8
.
Other standard associatives arrays libraries are : Data.IntMap
and Data.HasMap
Icon and Unicon
Icon and Unicon associative arrays are called tables. Any value may be used as a key including complex structures. Tables can have default values and they have no inherent size limitation growing from empty to whatever size is needed.
<lang icon>procedure main()
local t t := table() t["foo"] := "bar" write(t["foo"])
end</lang>
Inform 7
The Inform 7 equivalent of an associative array is a relation between values.
Static relation
<lang inform7>Hash Bar is a room.
Connection relates various texts to one number. The verb to be connected to implies the connection relation.
"foo" is connected to 12. "bar" is connected to 34. "baz" is connected to 56.
When play begins: [change values] now "bleck" is connected to 78; [check values] if "foo" is connected to 12, say "good."; if "bar" is not connected to 56, say "good."; [retrieve values] let V be the number that "baz" relates to by the connection relation; say "'baz' => [V]."; end the story.</lang>
Dynamic relation
<lang inform7>Hash Bar is a room.
When play begins: let R be a various-to-one relation of texts to numbers; [initialize the relation] now R relates "foo" to 12; now R relates "bar" to 34; now R relates "baz" to 56; [check values] if R relates "foo" to 12, say "good."; if R does not relate "bar" to 56, say "good."; [retrieve values] let V be the number that "baz" relates to by R; say "'baz' => [V]."; end the story.</lang>
Ioke
<lang ioke>{a: "a", b: "b"}</lang>
J
<lang J>coclass 'assocArray'
encode=: 'z', (a.{~;48 65 97(+ i.)&.>10 26 26) {~ 62x #.inv 256x #. a.&i. get=: ".@encode has=: 0 <: nc@<@encode set=:4 :'(encode x)=:y'</lang>
Example use:
<lang j> example=: conew 'assocArray'
'foo' set__example 1 2 3
1 2 3
'bar' set__example 4 5 6
4 5 6
get__example 'foo'
1 2 3
has__example 'foo'
1
bletch__example=: 7 8 9 get__example 'bletch'
7 8 9
codestroy__example</lang>
Note that J's symbols (http://www.jsoftware.com/help/dictionary/dsco.htm) might also be used for this purpose. However, symbols are not garbage collected within a J session (and, instead, a mechanism is provided to optionally preserve them across sessions).
Java
Defining the Map: <lang java5>Map<String, Integer> map = new HashMap<String, Integer>(); map.put("foo", 5); map.put("bar", 10); map.put("baz", 15); map.put("foo", 6);</lang> "Putting" a value for a key that already exists ("map.put("foo", 6)" in this example) will replace and return the old value for the key.
Initializing a Map as a class member: <lang java5>public static Map<String, Integer> map = new HashMap<String, Integer>(){{
put("foo", 5); put("bar", 10); put("baz", 15); put("foo", 6);
}};</lang>
Retrieving a value:
<lang java5>map.get("foo"); // => 6
map.get("invalid"); // => null</lang>
Note that it is possible to put null
as a value, so null
being returned by get
is not sufficient for determining that the key is not in the Map
. There is a containsKey
method for that.
Iterate over keys: <lang java5>for (String key: map.keySet())
System.out.println(key);</lang>
Iterate over values: <lang java5>for (int value: map.values())
System.out.println(value);</lang>
Iterate over key, value pairs: <lang java5>for (Map.Entry<String, Integer> entry: map.entrySet())
System.out.println(entry.getKey() + " => " + entry.getValue());</lang>
JavaScript
ECMAScript5.1 does not have associative arrays, however Objects (which are just an unordered bundle of name/value pairs) can be used like associative arrays. JavaScript Arrays may also be used, but Objects are the convention.
Javascript object property names (keys) are strings. Other types and expressions can be used with square bracket notation, they are evaluated and converted to strings and the result used as the property name. Using quotes on property names avoids potential collisions with reserved JavaScript key words. <lang javascript>var assoc = {};
assoc['foo'] = 'bar'; assoc['another-key'] = 3;
// dot notation can be used if the property name is a valid identifier assoc.thirdKey = 'we can also do this!'; assoc[2] = "the index here is the string '2'";
//using JavaScript's object literal notation var assoc = {
foo: 'bar', 'another-key': 3 //the key can either be enclosed by quotes or not
};
//iterating keys for (var key in assoc) {
// hasOwnProperty() method ensures the property isn't inherited if (assoc.hasOwnProperty(key)) { alert('key:"' + key + '", value:"' + assoc[key] + '"'); }
}</lang>
ECMAScript 6 (ES6) offers both a map and a weak map implementation. While Objects must use strings, Maps may use objects, functions, and numbers as keys in addition to strings. <lang javascript>var map = new Map(),
fn = function () {}, obj = {};
map.set(fn, 123); map.set(obj, 'abc'); map.set('key', 'val'); map.set(3, x => x + x);
map.get(fn); //=> 123 map.get(function () {}); //=> undefined because not the same function map.get(obj); //=> 'abc' map.get({}); //=> undefined because not the same object map.get('key'); //=> 'val' map.get(3); //=> (x => x + x)
map.size; //=> 4
//iterating using ES6 for..of syntax for (var key of map.keys()) {
console.log(key + ' => ' + map.get(key));
}</lang>
jq
Associative Arrays with String-Valued Keys
In jq, JSON objects can be used as associative arrays, it being understood that only strings can be used as keys. To avoid confusion, for the remainder of this section, we refer to JSON objects as such. Their type in jq is "object". <lang jq># An empty object: {}
- Its type:
{} | type
- "object"
- An object literal:
{"a": 97, "b" : 98}
- Programmatic object construction:
reduce ("a", "b", "c", "d") as $c ({}; . + { ($c) : ($c|explode[.0])} )
- {"a":97,"c":99,"b":98,"d":100}
- Same as above:
reduce range (97;101) as $i ({}; . + { ([$i]|implode) : $i })
- Addition of a key/value pair by assignment:
{}["A"] = 65 # in this case, the object being added to is {}
- Alteration of the value of an existing key:
{"A": 65}["A"] = "AA"</lang>
Associative Arrays with JSON-Valued Keys
In this subsection, we define addKey(key;value), getKey(key), and removeKey(key) to operate on a hash table for which the keys may be any JSON entities. This is done by defining a collisionless hash function. <lang jq>def collisionless:
if type == "object" then with_entries(.value = (.value|collisionless))|tostring elif type == "array" then map(collisionless)|tostring else (type[0:1] + tostring) end;
- WARNING: addKey(key;value) will erase any previous value associated with key
def addKey(key;value):
if type == "object" then . + { (key|collisionless): value } else {} | addKey(key;value) end;
def getKey(key): .[key|collisionless];
def removeKey(key): delpaths( [ [key|collisionless] ] );</lang> Example: <lang jq>{} | addKey(1;"one") | addKey(2; "two") | removeKey(1) | getKey(2)</lang> produces: <lang sh>"two"</lang>
Julia
We build dictionaries associating to some characters their code points, by listing the key/value pairs, through a dictionary comprehension, by creating an empty dictionary and filling it, by using the specific syntax associated to typed dictionaries and finally from two arrays using a constructor. <lang julia>julia> hash = {'a' => 97, 'b' => 98} # list keys/values {'a'=>97,'b'=>98}
julia> hash = {c => int(c) for c = 'a':'d'} # dict comprehension {'a'=>97,'c'=>99,'b'=>98,'d'=>100}
julia> hash['é'] = 233 ; hash # add an element {'a'=>97,'c'=>99,'b'=>98,'é'=>233,'d'=>100}
julia> hash = Dict() # create an empty dict Dict{Any,Any}()
julia> for c = 'a':'d' hash[c] = int(c) end ; hash # fill it {'a'=>97,'c'=>99,'b'=>98,'d'=>100}
julia> hash = (Char=>Int64)['a' => 97, 'b' => 98] # create a typed dict ['a'=>97,'b'=>98]
julia> hash["a"] = 1 # type mismatch ERROR: no method convert(Type{Char}, ASCIIString)
in setindex! at dict.jl:533
julia> hash = Dict(['a','b','c'], [97,98,99]) # constructor ['a'=>97,'c'=>99,'b'=>98]
julia> typeof(hash) # type is infered correctly Dict{Char,Int64} (constructor with 3 methods</lang>
K
Keys in a dictionary must be symbols (`symbol). <lang K> / creating an dictionary
d1:.((`foo;1); (`bar;2); (`baz;3))
/ extracting a value d1[`bar]
2</lang>
Another approach. <lang K> d2: .() / create empty dictionary
d2[`"zero"]:0 d2[`"one"]:1 d2[`"two"]:2
d2
.((`zero;0;)
(`one;1;) (`two;2;))</lang>
Extracting the keys and values. <lang K> !d2 / the keys `zero `one `two
d2[] / the values
0 1 2</lang>
Kotlin
<lang scala>fun main(args: Array<String>) {
// map definition: val map = mapOf("foo" to 5, "bar" to 10, "baz" to 15, "foo" to 6)
// retrieval: println(map["foo"]) // => 6 println(map["invalid"]) // => null
// check keys: println(map.contains("foo")) // => true println(map.contains("invalid")) // => false
// iterate over keys: for (k in map.keys) print("$k ") println()
// iterate over values: for (v in map.values) print("$v ") println()
// iterate over key, value pairs: for ((k, v) in map) println("$k => $v")
}</lang>
Lang5
<lang lang5>: dip swap '_ set execute _ ; : nip swap drop ;
- first 0 extract nip ; : second 1 extract nip ;
- assoc-in swap keys eq ;
- assoc-index' over keys swap eq [1] index collapse ;
- at swap assoc-index' subscript collapse second ;
- delete-at swap assoc-index' first remove ;
- keys 1 transpose first ;
- set-at
over 'dup dip assoc-in '+ reduce if 'dup dip delete-at then "swap 2 compress 1 compress" dip swap append ;
'foo 5 10 'bar rot set-at 'bar over at . 'hello 'bar rot set-at 20 'baz rot set-at .</lang>
Lasso
<lang Lasso>// In Lasso associative arrays are called maps
// Define an empty map local(mymap = map)
// Define a map with content local(mymap = map( 'one' = 'Monday', '2' = 'Tuesday', 3 = 'Wednesday' ))
// add elements to an existing map
- mymap -> insert('fourth' = 'Thursday')
// retrieve a value from a map
- mymap -> find('2') // Tuesday
'
'
- mymap -> find(3) // Wednesday, found by the key not the position
'
'
// Get all keys from a map
- mymap -> keys // staticarray(2, fourth, one, 3)
'
'
// Iterate thru a map and get values
with v in #mymap do {^
#v
'
'
^}
// Tuesday
Thursday
Monday
Wednesday
// Perform actions on each value of a map
- mymap -> foreach => {
#1 -> uppercase #1 -> reverse }
- mymap // map(2 = YADSEUT, fourth = YADSRUHT, one = YADNOM, 3 = YADSENDEW)</lang>
LFE
<lang lisp> (let* ((my-dict (: dict new))
(my-dict (: dict store 'key-1 '"value 1" my-dict)) (my-dict (: dict store 'key-2 '"value 2" my-dict))) (: io format '"size: ~p~n" (list (: dict size my-dict))) (: io format '"some data: ~p~n" (list (: dict fetch 'key-1 my-dict))))
</lang>
Liberty BASIC
Needs the sublist library from http://basic.wikispaces.com/SubList+Library since LB does not have built-in associative arrays. <lang lb> data "red", "255 50 50", "green", "50 255 50", "blue", "50 50 255" data "my fave", "220 120 120", "black", "0 0 0"
myAssocList$ =""
for i =1 to 5
read k$ read dat$ call sl.Set myAssocList$, k$, dat$
next i
print " Key 'green' is associated with data item "; sl.Get$( myAssocList$, "green") </lang>
Key 'green' is associated with data item 50 255 50
LiveCode
Livecode arrays are only associative, but can be accessed by ordinal if they are used as the key. <lang LiveCode>command assocArray
local tArray put "value 1" into tArray["key 1"] put 123 into tArray["key numbers"] put "a,b,c" into tArray["abc"] put "number of elements:" && the number of elements of tArray & return & \ "length of item 3:" && the length of tArray["abc"] & return & \ "keys:" && the keys of tArray
end assocArray</lang> Output <lang LiveCode>number of elements: 3 length of item 3: 5 keys: key numbers abc key 1</lang>
Logo
UCB Logo has "property lists" which associate names with values. They have their own namespace. <lang logo>pprop "animals "cat 5 pprop "animals "dog 4 pprop "animals "mouse 11 print gprop "animals "cat ; 5 remprop "animals "dog show plist "animals ; [mouse 11 cat 5]</lang>
Lua
Lua tables are Hashes <lang lua>hash = {} hash[ "key-1" ] = "val1" hash[ "key-2" ] = 1 hash[ "key-3" ] = {}</lang> Returns nil on unknown key.
Maple
Maple tables are hashed arrays. A table can be constructed by using the table constructor. <lang Maple>> T := table( [ (2,3) = 4, "foo" = 1, sin(x) = cos(x) ] );
T := table(["foo" = 1, sin(x) = cos(x), (2, 3) = 4])
> T[2,3];
4
> T[sin(x)];
cos(x)
> T["foo"];
1</lang>
New entries are added by assignment. <lang Maple>> T[ "bar" ] := 2;
T["bar"] := 2
> T[ "bar" ];
2</lang>
Entries can be removed as follows. <lang Maple>> T[ "foo" ] := evaln( T[ "foo" ] );
T["foo"] := T["foo"]
> T[ "foo" ];
T["foo"]</lang>
(The latter output indicates that T["foo"] is an unassigned name.)
Mathematica / Wolfram Language
<lang Mathematica>a[2] = "string"; a["sometext"] = 23;</lang>
MATLAB / Octave
MATLAB/Octave: structs
Associative arrays are called structs. The following methods of creating hash are equivalent.
<lang MATLAB> hash.a = 1;
hash.b = 2; hash.C = [3,4,5]; </lang>
alternatively <lang MATLAB> hash = [];
hash = setfield(hash,'a',1); hash = setfield(hash,'b',2); hash = setfield(hash,'C',[3,4,5]); </lang>
or <lang MATLAB> hash.('a') = 1;
hash.('b') = 2; hash.('C') = [3,4,5]; </lang>
>> disp(hash) scalar structure containing the fields: a = 1 b = 2 C = 3 4 5
Limitation: key must be a string containing only characters, digits and underscores, and the key string must start with a character.
MATLAB only: containers.Map
Use of containers.Map removes some restrictions on key types that structs have. Keys can all be numeric or all be strings. Values can be of any type. Key and value types cannot be changed after creation of the containers.Map object. <lang MATLAB>m = containers.Map({'a' 'b' 'C'}, [1 2 3]);</lang> is equivalent to <lang MATLAB>m = containers.Map; m('a') = 1; m('b') = 2; m('C') = 3;</lang> since the KeyType defaults to 'char'. For numeric keys, the key and value types must be specified at creation. <lang MATLAB>m = containers.Map([51 72 37], {'fiftyone' 'seventytwo' 'thirtyseven'});</lang> is equivalent to <lang MATLAB>m = containers.Map('KeyType', 'double', 'ValueType', 'any'); m(51) = 'fiftyone'; m(72) = 'seventytwo'; m(37) = 'thirtyseven';</lang> Usage:
>> m = containers.Map([51 72 37], {'fiftyone' 'seventytwo' 'thirtyseven'}); >> keys(m) ans = [37] [51] [72] >> values(m) ans = 'thirtyseven' 'fiftyone' 'seventytwo'
Maxima
<lang maxima>/* No need to declare anything, undeclared arrays are hashed */
h[1]: 6; h[9]: 2;
arrayinfo(h); [hashed, 1, [1], [9]]</lang>
Nemerle
This demonstrates two of several constructors, initializing the hashtable with a list of tuples or just specifying an initial capacity. <lang Nemerle>using System; using System.Console; using Nemerle.Collections;
module AssocArray {
Main() : void { def hash1 = Hashtable([(1, "one"), (2, "two"), (3, "three")]); def hash2 = Hashtable(3); foreach (e in hash1) hash2[e.Value] = e.Key; WriteLine("Enter 1, 2, or 3:"); def entry = int.Parse(ReadLine()); WriteLine(hash1[entry]); }
}</lang>
NetRexx
<lang NetRexx>/* NetRexx */
options replace format comments java crossref symbols
key0 = '0' key1 = 'key0'
hash = '.' -- Initialize the associative array 'hash' to '.' hash[key1] = 'value0' -- Set a specific key/value pair
say '<hash key="'key0'" value="'hash[key0]'" />' -- Display a value for a key that wasn't set say '<hash key="'key1'" value="'hash[key1]'" />' -- Display a value for a key that was set</lang>
- Output:
<hash key="0" value="." /> <hash key="key0" value="value0" />
Nim
<lang nim>import tables
var
hash = initTable[string, int]() # empty hash table hash2 = {"key1": 1, "key2": 2}.toTable # hash table with two keys hash3 = [("key1", 1), ("key2", 2)].toTable # hash table from tuple array hash4 = @[("key1", 1), ("key2", 2)].toTable # hash table from tuple seq value = hash2["key1"]
hash["spam"] = 1 hash["eggs"] = 2 hash.add("foo", 3)
echo "hash has ", hash.len, " elements" echo "hash has key foo? ", hash.hasKey("foo") echo "hash has key bar? ", hash.hasKey("bar")
echo "iterate pairs:" # iterating over (key, value) pairs for key, value in hash:
echo key, ": ", value
echo "iterate keys:" # iterating over keys for key in hash.keys:
echo key
echo "iterate values:" # iterating over values for key in hash.values:
echo key</lang>
- Output:
hash has 3 elements hash has key foo? true hash has key bar? false iterate pairs: eggs: 2 foo: 3 spam: 1 iterate keys: eggs foo spam iterate values: 2 3 1
Oberon-2
<lang oberon2> MODULE AssociativeArray; IMPORT
ADT:Dictionary, Object:Boxed, Out;
TYPE
Key = STRING; Value = Boxed.LongInt;
VAR
assocArray: Dictionary.Dictionary(Key,Value); iterK: Dictionary.IterKeys(Key,Value); iterV: Dictionary.IterValues(Key,Value); aux: Value; k: Key;
BEGIN
assocArray := NEW(Dictionary.Dictionary(Key,Value)); assocArray.Set("ten",NEW(Value,10)); assocArray.Set("eleven",NEW(Value,11)); aux := assocArray.Get("ten"); Out.LongInt(aux.value,0);Out.Ln; aux := assocArray.Get("eleven"); Out.LongInt(aux.value,0);Out.Ln;Out.Ln; (* Iterate keys *) iterK := assocArray.IterKeys(); WHILE (iterK.Next(k)) DO Out.Object(k);Out.Ln END; Out.Ln; (* Iterate values *) iterV := assocArray.IterValues(); WHILE (iterV.Next(aux)) DO Out.LongInt(aux.value,0);Out.Ln END
END AssociativeArray.
</lang>
Objeck
Object parameters must be implicitly casted to the types expected by the method that's called.
Associative map
<lang objeck>
- create map
map := StringMap->New();
- insert
map->Insert("two", IntHolder->New(2)->As(Base)); map->Insert("thirteen", IntHolder->New(13)->As(Base)); map->Insert("five", IntHolder->New(5)->As(Base)); map->Insert("seven", IntHolder->New(7)->As(Base));
- find
map->Find("thirteen")->As(IntHolder)->GetValue()->PrintLine(); map->Find("seven")->As(IntHolder)->GetValue()->PrintLine(); </lang>
Hash table
<lang objeck>
- create map
map := StringHash->New();
- insert
map->Insert("two", IntHolder->New(2)->As(Base)); map->Insert("thirteen", IntHolder->New(13)->As(Base)); map->Insert("five", IntHolder->New(5)->As(Base)); map->Insert("seven", IntHolder->New(7)->As(Base));
- find
map->Find("thirteen")->As(IntHolder)->GetValue()->PrintLine(); map->Find("seven")->As(IntHolder)->GetValue()->PrintLine(); </lang>
Objective-C
and
You can use a NSDictionary to create an immutable hash. A dictionary can contain only objects; if you want store non objects like integer, you have to box it in NSNumber. <lang objc>NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
@"Joe Doe", @"name", [NSNumber numberWithUnsignedInt:42], @"age", [NSNull null], @"extra", nil];</lang>
The same as the above with the new literal syntax in clang 3.1+ / Apple LLVM Compiler 4.0+ (XCode 4.4+) : <lang objc>NSDictionary *dict = @{
@"name": @"Joe Doe", @"age": @42, @"extra": [NSNull null], };</lang>
To create a mutable dictionary, use NSMutableDictionary: <lang objc>NSMutableDictionary *dict = [NSMutableDictionary dictionary]; [dict setObject:@"Joe Doe" forKey:@"name"]; [dict setObject:[NSNumber numberWithInt:42] forKey:@"age"];</lang>
You can access value with objectForKey:. If a key does not exists, nil is returned. <lang objc>NSString *name = [dict objectForKey:@"name"]; unsigned age = [dict objectForKey:@"age"] unsignedIntValue]; id missing = [dict objectForKey:@"missing"];</lang>
OCaml
Hash table
A simple idiom to create a hash table mapping strings to integers: <lang ocaml>let hash = Hashtbl.create 0;; List.iter (fun (key, value) -> Hashtbl.add hash key value)
["foo", 5; "bar", 10; "baz", 15];;</lang>
To retrieve a value: <lang ocaml>let bar = Hashtbl.find hash "bar";; (* bar = 10 *)</lang> To retrieve a value, returning a default if the key is not found: <lang ocaml>let quux = try Hashtbl.find hash "quux" with Not_found -> some_value;;</lang>
Binary tree
A simple idiom to create a persistent binary tree mapping strings to integers: <lang ocaml>module String = struct
type t = string let compare = Pervasives.compare
end module StringMap = Map.Make(String);;
let map =
List.fold_left (fun map (key, value) -> StringMap.add key value map) StringMap.empty ["foo", 5; "bar", 10; "baz", 15]
- </lang>
To retrieve a value: <lang ocaml>let bar = StringMap.find "bar" map;; (* bar = 10 *)</lang> To retrieve a value, returning a default if the key is not found: <lang ocaml>let quux = try StringMap.find "quux" map with Not_found -> some_value;;</lang>
Association list
Some list functions allow you to use a list as an associative map, although the access time is O(N) so a Hashtbl or binary tree should be used for larger data-sets. <lang Ocaml>let dict = ["foo", 5; "bar", 10; "baz", 15]
(* retrieve value *) let bar_num = try List.assoc "bar" dict with Not_found -> 0;;
(* see if key exists *) print_endline (if List.mem_assoc "foo" dict then "key found" else "key missing")</lang>
ooRexx
ooRexx has multiple classes that create index-to-item associative relationships.
- Directory -- a mapping for a string index to an object instance
- Table -- a mapping for an object index (of any class) to an object instance. Index equality is determined by the "==" method.
- Relation -- a one-to-many mapping for an object index (of any class) to object instances. Index equality is determined by the "==" method.
- IdentityTable -- a mapping for an object index (of any class) to an object instance. Index equality is determined by unique object identity rather than equality.
- Stem -- The class backing ooRexx stem variables, which is also a first-class collection class.
All of the MapCollections are very similar in usage. We'll use Directory for the examples here.
Defining the map: <lang ooRexx>map = .directory~new map["foo"] = 5 map["bar"] = 10 map["baz"] = 15 map["foo"] = 6 </lang> "Putting" a value for a key that already exists ("map["foo"] = 6" in this example) will replace and return the old value for the key.
Retrieving a value:
<lang ooRexx>item = map["foo"] -- => 6
item = map["invalid"] -- => .nil</lang>
Note that it is possible to put .nil
as a value, so .nil
being returned as a value is not sufficient for determining that the key is not in the collection. There is a hasIndex
method for that.
Iterate over keys: <lang ooRexx>loop key over map
say key
end </lang> Iterate over values: <lang ooRexx>loop value over map~allItems
say value
end </lang> Iterate over key, value pairs: <lang ooRexx> s = map~supplier loop while s~available
say s~index "=>" s~item s~next
end </lang>
OxygenBasic
Not very efficient but the 'find' method could be optimised very easily. <lang oxygenbasic> def n 200
Class AssociativeArray '=====================
indexbase 1 string s[n] sys max
method find(string k) as sys sys i,e e=max*2 for i=1 to e step 2 if k=s[i] then return i next end method
method dat(string k) as string sys i=find(k) if i then return s[i+1] end method
method dat(string k, d) as sys sys i=find(k) if i=0 then if max>=n print "Array overflow" : return 0 end if max+=1 i=max*2-1 s[i]=k end if s[i+1]=d return i end method
end class
'====
'TEST
'====
AssociativeArray A
'fill A.s<={"shoes","LC1", "ships","LC2", "sealingwax","LC3", "cabbages","LC4", "kings","LC5"} A.max=5 'access print A.dat("ships") 'result LC2 A.dat("computers")="LC99" ' print A.dat("computers") 'result LC99 </lang>
Oz
A mutable map is called a 'dictionary' in Oz: <lang oz>declare
Dict = {Dictionary.new}
in
Dict.foo := 5 Dict.bar := 10 Dict.baz := 15 Dict.foo := 20
{Inspect Dict}</lang>
'Records' can be consideres immutable maps: <lang oz>declare
Rec = name(foo:5 bar:10 baz:20)
in
{Inspect Rec}</lang>
PARI/GP
GP's associative arrays are called maps, and can be created like so: <lang parigp>M = Map();</lang> They can be used as follows: <lang parigp>mapput(M, "key", "value"); mapput(M, 17, "different value"); mapput(M, "key2", Pi); mapget(M, "key2") \\ returns Pi mapisdefined(M, "key3") \\ returns 0 mapdelete(M, "key2");</lang>
In PARI the commands are gtomap
, mapput
, mapget
, mapisdefined
, and mapdelete
. You can also use the solutions in Associative arrays/Creation/C.
Perl
Hash
Definition: <lang perl># using => key does not need to be quoted unless it contains special chars my %hash = (
key1 => 'val1', 'key-2' => 2, three => -238.83, 4 => 'val3',
);
- using , both key and value need to be quoted if containing something non-numeric in nature
my %hash = (
'key1', 'val1', 'key-2', 2, 'three', -238.83, 4, 'val3',
);</lang>
Use: <lang perl>print $hash{key1};
$hash{key1} = 'val1';
@hash{'key1', 'three'} = ('val1', -238.83);</lang>
HashRef
Definition: <lang perl>my $hashref = {
key1 => 'val1', 'key-2' => 2, three => -238.83, 4 => 'val3',
}</lang>
Use: <lang perl>print $hash->{key1};
$hash->{key1} = 'val1';
@hash->{'key1', 'three'} = ('val1', -238.83);</lang>
Key Types
Keys are strings. Anything else is stringized in Perl's usual ways, which generally means integers work too, but for floating point care might be needed against round-off.
Various tie
modules implement keys of other types, usually by constructing underlying string keys of suitable nature. For example Tie::RefHash
allows objects (blessed or unblessed) as keys.
Perl 6
The fatarrow, =>
, is no longer just a quoting comma; it now constructs a Pair
object. But you can still define a hash with an ordinary list of even length.
<lang perl6>my %h1 = key1 => 'val1', 'key-2' => 2, three => -238.83, 4 => 'val3'; my %h2 = 'key1', 'val1', 'key-2', 2, 'three', -238.83, 4, 'val3';</lang>
Creating a hash from two lists using a metaoperator.
<lang perl6>my @a = 1..5; my @b = 'a'..'e'; my %h = @a Z=> @b;</lang>
Hash elements and hash slices now use the same sigil as the whole hash. This is construed as a feature. Curly braces no longer auto-quote, but Perl 6's qw
(shortcut < ... >
) now auto-subscripts.
<lang perl6>say %h1{'key1'}; say %h1<key1>; %h1<key1> = 'val1'; %h1<key1 three> = 'val1', -238.83;</lang>
Special syntax is no longer necessary to access a hash stored in a scalar.
<lang perl6>my $h = {key1 => 'val1', 'key-2' => 2, three => -238.83, 4 => 'val3'}; say $h<key1>;</lang>
Keys are of type Str or Int by default. The type of the key can be provided.
<lang perl6> my %hash{Any}; # same as %hash{*} class C {}; my %cash{C}; %cash{C.new} = 1;</lang>
Phix
Associative arrays are supported via just eight simple routines, with no specialised syntax.
Any key can be mapped to any value, and both can be anything (integer|float|string|[nested]sequence, including 0|NULL).
The setd(key,val) procedure is self-explanatory, except for an optional third parameter which is explained below.
The getd(key) function returns the associated data or 0 for non-existent keys: if that might be a valid value see getd_index().
By default, all keys and values are entered into one central dictionary. You can create multiple dictionaries by calling integer tid=new_dict(), and pass that as an additional (final) parameter to the other routines (taking care not to miss any). When you have no further use for it, an entire dictionary can be removed by invoking destroy_dict(tid). <lang Phix>setd("one",1) setd(2,"duo") setd({3,4},{5,"six"}) ?getd("one") -- shows 1 ?getd({3,4}) -- shows {5,"six"} ?getd(2) -- shows "duo" deld(2) ?getd(2) -- shows 0</lang>
PHP
<lang php>$array = array(); $array = []; // Simpler form of array initialization $array['foo'] = 'bar'; $array['bar'] = 'foo';
echo($array['foo']); // bar echo($array['moo']); // Undefined index
// Alternative (inline) way $array2 = array('fruit' => 'apple',
'price' => 12.96, 'colour' => 'green');
// Another alternative (simpler) way $array2 = ['fruit' => 'apple',
'price' => 12.96, 'colour' => 'green'];
// Check if key exists in the associative array echo(isset($array['foo'])); // Faster, but returns false if the value of the element is set to null echo(array_key_exists('foo', $array)); // Slower, but returns true if the value of the element is null</lang>
Iterate over key/value
<lang php>foreach($array as $key => $value) {
echo "Key: $key Value: $value";
}</lang>
PicoLisp
Here we use symbol properties. Other possiblities could be index trees or association lists.
<lang PicoLisp>(put 'A 'foo 5) (put 'A 'bar 10) (put 'A 'baz 15) (put 'A 'foo 20)
- (get 'A 'bar)
-> 10
- (get 'A 'foo)
-> 20
- (show 'A)
A NIL
foo 20 bar 10 baz 15</lang>
PL/I
<lang pli>*process source xref attributes or(!);
assocarr: Proc Options(main); Dcl 1 aa, 2 an Bin Fixed(31) Init(0), 2 pairs(100), 3 key Char(10) Var, 3 val Char(10) Var; Dcl hi Char(10) Value((high(10))); Dcl i Bin Fixed(31); Dcl k Char(10) Var;
Call aadd('1','spam'); Call aadd('2','eggs'); Call aadd('3','foo'); Call aadd('2','spam'); Call aadd('4','spam');
Put Skip(' '); Put Edit('Iterate over keys')(Skip,a); Do i=1 To an; k=key(i); Put Edit('>'!!k!!'< => >'!!aacc(k)!!'<')(Skip,a); End;
aadd: Proc(k,v); Dcl (k,v) Char(*) Var; If aacc(k)^=hi Then Put Edit('Key >',k,'< would be a duplicate, not added.') (Skip,a,a,a); Else Do; an+=1; key(an)=k; val(an)=v; Put Edit('added >'!!k!!'< -> '!!v!!'<')(Skip,a); End; End;
aacc: Proc(k) Returns(Char(10) Var); Dcl k Char(*) Var; Dcl v Char(10) Var; Dcl i Bin Fixed(31); Do i=1 To an; If key(i)=k Then Return(val(i)); End; Return(hi); End;
End;</lang>
- Output:
added >1< -> spam< added >2< -> eggs< added >3< -> foo< Key >2< would be a duplicate, not added. added >4< -> spam< Iterate over keys >1< => >spam< >2< => >eggs< >3< => >foo< >4< => >spam<
PL/SQL
PL/SQL allows associative arrays defined on two different keys types: Varchar2 or PLS/Integer
Associative Arrays are a PL/SQL only construct. Unlike Oracle Nested Tables or Varrays (the other two types of Oracle collections), associative arrays do not have a corresponding type which can be stored natively in the database. The following code will also show a workaround for this feature.
The following example code is a "record definition", which has nothing to do with associative arrays:- <lang PL/SQL>DECLARE
type ThisIsNotAnAssocArrayType is record ( myShape VARCHAR2(20), mySize number, isActive BOOLEAN ); assocArray ThisIsNotAnAssocArrayType ;
BEGIN
assocArray.myShape := 'circle';
dbms_output.put_line ('assocArray.myShape: ' || assocArray.myShape); dbms_output.put_line ('assocArray.mySize: ' || assocArray.mySize);
END; /</lang>
Pop11
<lang pop11>;;; Create expandable hash table of initial size 50 and with default
- value 0 (default value is returned when the item is absent).
vars ht = newmapping([], 50, 0, true);
- Set value corresponding to string 'foo'
12 -> ht('foo');
- print it
ht('foo') =>
- Set value corresponding to vector {1 2 3}
17 -> ht({1 2 3});
- print it
ht({1 2 3}) =>
- Set value corresponding to number 42 to vector {0 1}
{0 1} -> ht(42);
- print it
ht(42) =>
- Iterate over keys printing keys and values.
appproperty(ht, procedure (key, value); printf(value, '%p\t'); printf(key, '%p\n'); endprocedure);</lang>
PostScript
<lang postscript>
<</a 100 /b 200 /c 300>> dup /a get =
</lang>
Potion
<lang potion>mydictionary = (red=0xff0000, green=0x00ff00, blue=0x0000ff)
redblue = "purple" mydictionary put(redblue, 0xff00ff)
255 == mydictionary("blue") 65280 == mydictionary("green") 16711935 == mydictionary("purple")</lang>
PowerShell
Am empty hash table can be created with <lang powershell>$hashtable = @{}</lang> A hash table can be initialized with key/value pairs: <lang powershell>$hashtable = @{
"key1" = "value 1" "key2" = 5
}</lang> Individual values can be assigned or replaced by either using a property-style access method or indexing into the table with the given key: <lang powershell>$hashtable.foo = "bar" $hashtable['bar'] = 42 $hashtable."a b" = 3.14 # keys can contain spaces, property-style access needs quotation marks, then $hashtable[5] = 8 # keys don't need to be strings</lang> Similarly, values can be retrieved using either syntax: <lang powershell>$hashtable.key1 # value 1 $hashtable['key2'] # 5</lang>
A shortcut to CREATE an OBJECT with empty fields: <lang powershell>$addressObj= "" | Select-Object nameStr,street1Str,street2Str,cityStr,stateStr,zipStr $addressObj.nameStr = [string]"FirstName LastName" $addressObj.street1Str= [string]"1 Main Street" $addressObj.cityStr= [string]"Washington DC" $addressObj.stateStr= [string]"DC" $addressObj.zipStr= [string]"20009" </lang>
Prolog
We use the facts table for this purpose. <lang prolog> mymap(key1,value1). mymap(key2,value2).
?- mymap(key1,V).
V = value1
</lang>
PureBasic
Hashes are a built-in type called Map in Purebasic.
<lang purebasic>NewMap dict.s() dict("country") = "Germany" Debug dict("country")</lang>
Python
Hashes are a built-in type called dictionaries (or mappings) in Python.
<lang python>hash = dict() # 'dict' is the dictionary type. hash = dict(red="FF0000", green="00FF00", blue="0000FF") hash = { 'key1':1, 'key2':2, } value = hash[key]</lang>
Numerous methods exist for the mapping type http://docs.python.org/lib/typesmapping.html
<lang python># empty dictionary d = {} d['spam'] = 1 d['eggs'] = 2
- dictionaries with two keys
d1 = {'spam': 1, 'eggs': 2} d2 = dict(spam=1, eggs=2)
- dictionaries from tuple list
d1 = dict([('spam', 1), ('eggs', 2)]) d2 = dict(zip(['spam', 'eggs'], [1, 2]))
- iterating over keys
for key in d:
print key, d[key]
- iterating over (key, value) pairs
for key, value in d.iteritems():
print key, value</lang>
Note: Python dictionary keys can be of any arbitrary "hashable" type. The following contains several distinct key value pairs:
<lang python>myDict = { '1': 'a string', 1: 'an integer', 1.0: 'a floating point number', (1,): 'a tuple' }</lang>
(Some other languages such as awk and Perl evaluate all keys such that numerically or lexically equivalent expressions become identical entries in the hash or associative array).
User defined classes which implement the __hash__() special method can also be used as dictionary keys. It's the responsibility of the programmer to ensure the properties of the resultant hash value. The instance object's unique ID (accessible via the id() built-in function) is commonly used for this purpose.
R
R lacks a native representation of key-value pairs, but different structures allow named elements, which provide similar functionality.
environment example
<lang r>> env <- new.env() > env"x" <- 123 > env"x"</lang>
[1] 123
<lang r>> index <- "1" > envindex <- "rainfed hay" > envindex</lang>
[1] "rainfed hay"
<lang r>> env"1"</lang>
[1] "rainfed hay"
<lang r>> env</lang>
<environment: 0xb7cd560>
<lang r>> print(env)</lang>
<environment: 0xb7cd560>
vector example
<lang r>> x <- c(hello=1, world=2, "!"=3) > print(x)</lang>
hello world ! 1 2 3
<lang r>> print(names(x))</lang>
[1] "hello" "world" "!"
<lang r>print(unname(x))</lang>
[1] 1 2 3
list example
<lang R>> a <- list(a=1, b=2, c=3.14, d="xyz") > print(a)</lang>
$a [1] 1 $b [1] 2 $c [1] 3.14 $d [1] "xyz"
<lang r>> print(names(a))</lang>
[1] "a" "b" "c" "d"
<lang r>> print(unname(a))</lang>
[[1]] [1] 1 [[2]] [1] 2 [[3]] [1] 3.14 [[4]] [1] "xyz"
Racket
In Racket, hash tables are natively supported and encouraged over association lists in many cases. Data structures that behave like dictionaries support a unified interface.
<lang racket>
- lang racket
- a-lists
(define a-list '((a . 5) (b . 10))) (assoc a-list 'a) ; => '(a . 5)
- hash tables
(define table #hash((a . 5) (b . 10))) (hash-ref table 'a) ; => 5
- dictionary interface
(dict-ref a-list 'a) ; => 5 (dict-ref table 'a) ; => 5 </lang>
Raven
<lang raven>{ 'a' 1 'b' 2 'c' 3.14 'd' 'xyz' } as a_hash a_hash print
hash (4 items)
a => 1 b => 2 c => 3.14 d => "xyz"
a_hash 'c' get # get key 'c' 6.28 a_hash 'c' set # set key 'c' a_hash.'c' # get key 'c' shorthand 6.28 a_hash:'c' # set key 'c' shorthand</lang>
Null is returned for unknown keys.
Retro
<lang Retro>with hashTable' hashTable constant table
table %{ first = 100 }% table %{ second = "hello, world!" keepString %}
table @" first" putn table @" second" puts</lang>
REXX
version 1
Associative arrays are called stem variables in Rexx. <lang Rexx>/* Rexx */
key0 = '0' key1 = 'key0'
stem. = '.' /* Initialize the associative array 'stem' to '.' */ stem.key1 = 'value0' /* Set a specific key/value pair */
Say 'stem.key0= 'stem.key /* Display a value for a key that wasn't set */ Say 'stem.key1= 'stem.key1 /* Display a value for a key that was set */</lang>
- Output:
stem.key0= . stem.key1= value0
version 2
<lang rexx>/*REXX program shows how to set/display values for an associative array.*/ /*┌────────────────────────────────────────────────────────────────────┐
│ The (below) two REXX statements aren't really necessary, but it │ │ shows how to define any and all entries in a associative array so │ │ that if a "key" is used that isn't defined, it can be displayed to │ │ indicate such, or its value can be checked to determine if a │ │ particular associative array element has been set (defined). │ └────────────────────────────────────────────────────────────────────┘*/
stateC.=' [not defined yet] ' /*sets any/all state capitols. */ stateN.=' [not defined yet] ' /*sets any/all state names. */ /*┌────────────────────────────────────────────────────────────────────┐
│ In REXX, when a "key" is used, it's normally stored (internally) │ │ as uppercase characters (as in the examples below). Actually, any │ │ characters can be used, including blank(s) and non-displayable │ │ characters (including '00'x, 'ff'x, commas, periods, quotes, ...).│ └────────────────────────────────────────────────────────────────────┘*/
stateC.ca='Sacramento'; stateN.ca='California' stateC.nd='Bismarck' ; stateN.nd='North Dakota' stateC.mn='St. Paul' ; stateN.mn='Minnesota' stateC.dc='Washington'; stateN.dc='District of Columbia' stateC.ri='Providence'; stateN.ri='Rhode Island and Providence Plantations'
say 'capital of California is' stateC.ca say 'capital of Oklahoma is' stateC.ok yyy='RI' say 'capital of' stateN.yyy "is" stateC.yyy
/*stick a fork in it, we're done.*/</lang>
- Output:
capital of California is Sacramento capital of Oklahoma is [not defined yet] capital of Rhode Island and Providence Plantations is Providence
RLaB
Associative arrays are called lists in RLaB. <lang RLaB> x = <<>>; // create an empty list using strings as identifiers. x.red = strtod("0xff0000"); // RLaB doesn't deal with hexadecimal numbers directly. Thus we x.green = strtod("0x00ff00"); // convert it to real numbers using strtod function. x.blue = strtod("0x0000ff");
// print content of a list for (i in members(x)) { printf("%8s %06x\n", i, int(x.[i])); } // we have to use int function to convert reals to integers so "%x" format works
// deleting a key/value clear (x.red);
// we can also use numeric identifiers in the above example xid = members(x); // this is a string array
for (i in 1:length(xid)) { printf("%8s %06x\n", xid[i], int(x.[ xid[i] ])); }
// Finally, we can use numerical identifiers // Note: members function orders the list identifiers lexicographically, in other words // instead of, say, 1,2,3,4,5,6,7,8,9,10,11 members returns 1,10,11,2,3,4,5,6,7,8,9 x = <<>>; // create an empty list for (i in 1:5) { x.[i] = i; } // assign to the element of list i the real value equal to i.
</lang>
Ruby
A hash object that returns nil for unknown keys <lang ruby>hash={} hash[666]='devil' hash[777] # => nil hash[666] # => 'devil'</lang>
A hash object that returns 'unknown key' for unknown keys <lang ruby>hash=Hash.new('unknown key') hash[666]='devil' hash[777] # => 'unknown key' hash[666] # => 'devil'</lang>
A hash object that returns "unknown key #{key}" for unknown keys <lang ruby>hash=Hash.new{|h,k| "unknown key #{k}"} hash[666]='devil' hash[777] # => 'unknown key 777' hash[666] # => 'devil'</lang>
A hash object that adds "key #{key} was added at #{Time.now}" to the hash the first time an unknown key is seen <lang ruby>hash=Hash.new{|h,k|h[k]="key #{k} was added at #{Time.now}"} hash[777] # => 'key 777 was added at Sun Apr 03 13:49:57 -0700 2011' hash[555] # => 'key 555 was added at Sun Apr 03 13:50:01 -0700 2011' hash[777] # => 'key 777 was added at Sun Apr 03 13:49:57 -0700 2011'</lang>
Rust
<lang rust>use std::collections::HashMap; fn main() {
let mut olympic_medals = HashMap::new(); olympic_medals.insert("United States", (1072, 859, 749)); olympic_medals.insert("Soviet Union", (473, 376, 355)); olympic_medals.insert("Great Britain", (246, 276, 284)); olympic_medals.insert("Germany", (252, 260, 270)); println!("{:?}", olympic_medals);
}</lang>
Sather
<lang sather>class MAIN is
main is -- creation of a map between strings and integers map ::= #MAP{STR, INT};
-- add some values map := map.insert("red", 0xff0000); map := map.insert("green", 0xff00); map := map.insert("blue", 0xff);
#OUT + map + "\n"; -- show the map...
-- test if "indexes" exist #OUT + map.has_ind("red") + "\n"; #OUT + map.has_ind("carpet") + "\n";
-- retrieve a value by index #OUT + map["green"] + "\n"; end;
end; </lang>
Scala
<lang Scala>// immutable maps var map = Map(1 -> 2, 3 -> 4, 5 -> 6) map(3) // 4 map = map + (44 -> 99) // maps are immutable, so we have to assign the result of adding elements map.isDefinedAt(33) // false map.isDefinedAt(44) // true</lang>
<lang scala>// mutable maps (HashSets) import scala.collection.mutable.HashMap val hash = new HashMap[Int, Int] hash(1) = 2 hash += (1 -> 2) // same as hash(1) = 2 hash += (3 -> 4, 5 -> 6, 44 -> 99) hash(44) // 99 hash.contains(33) // false hash.isDefinedAt(33) // same as contains hash.contains(44) // true</lang>
<lang scala>// iterate over key/value hash.foreach {e => println("key "+e._1+" value "+e._2)} // e is a 2 element Tuple // same with for syntax for((k,v) <- hash) println("key " + k + " value " + v)</lang>
<lang scala>// items in map where the key is greater than 3 map.filter {k => k._1 > 3} // Map(5 -> 6, 44 -> 99) // same with for syntax for((k, v) <- map; if k > 3) yield (k,v)</lang>
Scheme
Scheme has association lists (alists), which are inefficient, ordered maps with arbitrary keys and values. <lang scheme>(define my-dict '((a b) (1 hello) ("c" (a b c))) (assoc 'a my-dict) ; evaluates to '(a b)</lang>
Hash tables are provided by SRFI-69 [1]. Many Scheme implementation also provide native hash tables.
<lang scheme>(define my-alist '((a b) (1 hello) ("c" (a b c))) (define my-hash (alist->hash-table my-alist))</lang>
The R6RS standard specifies support for hashtables in the standard libraries document.
<lang scheme>#!r6rs
(import (rnrs base)
(rnrs hashtables (6)))
(define my-hash (make-hashtable equal-hash equal?)) (hashtable-set! my-hash 'a 'b) (hashtable-set! my-hash 1 'hello) (hashtable-set! my-hash "c" '(a b c))</lang>
Seed7
Seed7 uses the type hash to support associative arrays.
<lang seed7>$ include "seed7_05.s7i";
- Define hash type
const type: myHashType is hash [string] integer;
- Define hash table
var myHashType: aHash is myHashType.value;
const proc: main is func
local var string: stri is ""; var integer: number is 0; begin # Add elements aHash @:= ["foo"] 42; aHash @:= ["bar"] 100;
# Check presence of an element if "foo" in aHash then
# Access an element writeln(aHash["foo"]); end if;
# Change an element aHash @:= ["foo"] 7;
# Remove an element excl(aHash, "foo");
# Loop over the hash values for number range aHash do writeln(number); end for;
# Loop over the hash keys for key stri range aHash do writeln(stri); end for;
# Loop over hash keys and values for number key stri range aHash do writeln("key: " <& stri <& ", value: " <& number); end for; end func;</lang>
Sidef
<lang ruby>var hash = Hash.new(
key1 => 'value1', key2 => 'value2',
);
- Add a new key-value pair
hash{:key3} = 'value3';</lang>
Slate
<lang slate>Dictionary new*, 'MI' -> 'Michigan', 'MN' -> 'Minnesota'</lang>
Smalltalk
<lang smalltalk>states := Dictionary new. states at: 'MI' put: 'Michigan'. states at: 'MN' put: 'Minnesota'.</lang>
SNOBOL4
<lang snobol4> t = table() t<"red"> = "#ff0000" t<"green"> = "#00ff00" t<"blue"> = "#0000ff"
output = t<"red"> output = t<"blue"> output = t<"green"> end</lang>
SQL
<lang SQL> REM Create a table to associate keys with values CREATE TABLE associative_array ( KEY_COLUMN VARCHAR2(10), VALUE_COLUMN VARCHAR2(100)); . REM Insert a Key Value Pair INSERT (KEY_COLUMN, VALUE_COLUMN) VALUES ( 'VALUE','KEY');. REM Retrieve a key value pair SELECT aa.value_column FROM associative_array aa where aa.key_column = 'KEY'; </lang>
Swift
<lang swift>// make an empty map var a = [String: Int]() // or var b: [String: Int] = [:]
// make an empty map with an initial capacity var c = [String: Int](minimumCapacity: 42)
// set a value c["foo"] = 3
// make a map with a literal var d = ["foo": 2, "bar": 42, "baz": -1]</lang>
Tcl
All arrays in Tcl are associative.
<lang tcl># Create one element at a time: set hash(foo) 5
- Create in bulk:
array set hash {
foo 5 bar 10 baz 15
}
- Access one element:
set value $hash(foo)
- Output all values:
foreach key [array names hash] {
puts $hash($key)
}</lang>
Tcl also provides associative map values (called “dictionaries”) from 8.5 onwards.
<lang tcl># Create in bulk set d [dict create foo 5 bar 10 baz 15]
- Create/update one element
dict set d foo 5
- Access one value
set value [dict get $d foo]
- Output all values
dict for {key value} $d {
puts $value
}
- Alternatively...
foreach value [dict values $d] {
puts $value
}
- Output the whole dictionary (since it is a Tcl value itself)
puts $d</lang>
Toka
Toka provides associative arrays via a library.
<lang toka>needs asarray
( create an associative array ) 1024 cells is-asarray foo
( store 100 as the "first" element in the array ) 100 " first" foo asarray.put
( store 200 as the "second" element in the array ) 200 " second" foo asarray.put
( obtain and print the values ) " first" foo asarray.get . " second" foo asarray.get .</lang>
UNIX Shell
<lang bash>typeset -A hash hash=( [key1]=val1 [key2]=val2 ) hash[key3]=val3 echo "${hash[key3]}"</lang>
assigning values is the same as ksh, but to declare the variable as an associative array: <lang bash>declare -A hash</lang>
UnixPipes
A key value file can be considered as an associative array <lang bash>map='p.map'
function init() { cat <<EOF > $map apple a boy b cat c dog d elephant e EOF }
function put() {
k=$1; v=$2; del $k echo $v $k >> $map }
function get() {
k=$1 for v in $(cat $map | grep "$k$"); do echo $v break done }
function del() {
k=$1 temp=$(mktemp) mv $map $temp cat $temp | grep -v "$k$" > $map
}
function dump() {
echo "-- Dump begin --" cat $map echo "-- Dump complete --"
}
init get c put c cow get c dump</lang>
Vala
<lang vala> using Gee;
void main(){
var map = new HashMap<string, int>(); // creates a HashMap with keys of type string, and values of type int
// two methods to set key,value pair map["one"] = 1; map["two"] = 2;
map.set("four", 4); map.set("five", 5);
// two methods of getting key,value pair stdout.printf("%d\n", map["one"]);
stdout.printf("%d\n", map.get("two"));
} </lang>
Compile with flag:
--pkg gee-1.0
Vim Script
Dictionary keys are always strings. <lang vim>" Creating a dictionary with some initial values let dict = {"one": 1, "two": 2}
" Retrieving a value let two_a = dict["two"] let two_b = dict.two let two_c = get(dict, "two", "default value for missing key")
" Modifying a value let dict["one"] = 1.0 let dict.two = 2.0
" Adding a new value let dict["three"] = 3 let dict.four = 4
" Removing a value let one = remove(dict, "one") unlet dict["two"] unlet dict.three</lang>
Visual FoxPro
Visual FoxPro has a collection class which can be used for this. <lang vfp> LOCAL loCol As Collection, k, n, o CLEAR
- !* Example using strings
loCol = NEWOBJECT("Collection") loCol.Add("Apples", "A") loCol.Add("Oranges", "O") loCol.Add("Pears", "P") n = loCol.Count ? "Items:", n
- !* Loop through the collection
k = 1 FOR EACH o IN loCol FOXOBJECT
? o, loCol.GetKey(k) k = k + 1
ENDFOR
- !* Get an item by its key
? loCol("O") ?
- !* Example using objects
LOCAL loFruits As Collection loFruits = NEWOBJECT("Collection") loFruits.Add(CREATEOBJECT("fruit", "Apples"), "A") loFruits.Add(CREATEOBJECT("fruit", "Oranges"), "O") loFruits.Add(CREATEOBJECT("fruit", "Pears"), "P")
- !* Loop through the collection
k = 1 FOR EACH o IN loFruits FOXOBJECT
? o.Name, loFruits.GetKey(k) k = k + 1
ENDFOR
- !* Get an item name by its key
? loFruits("P").Name
DEFINE CLASS fruit As Custom
PROCEDURE Init(tcName As String)
THIS.Name = tcName
ENDPROC
ENDDEFINE
</lang>
Wart
<lang wart>h <- (table 'a 1 'b 2) h 'a => 1</lang>
XPL0
<lang XPL0>include c:\cxpl\stdlib; char Dict(10,10); int Entries;
proc AddEntry(Letter, Greek); \Insert entry into associative array char Letter, Greek; [Dict(Entries,0):= Letter; StrCopy(Greek, @Dict(Entries,1)); Entries:= Entries+1; \(limit checks ignored for simplicity) ];
func Lookup(Greek); \Given Greek name return English letter char Greek; int I; [for I:= 0, Entries-1 do
if StrCmp(Greek, @Dict(I,1)) = 0 then return Dict(I,0);
return ^?; ];
[Entries:= 0; AddEntry(^A, "alpha"); AddEntry(^D, "delta"); AddEntry(^B, "beta"); AddEntry(^C, "gamma"); ChOut(0, Lookup("beta")); CrLf(0); ChOut(0, Lookup("omega")); CrLf(0); ]</lang>
For greater speed a hashing algorithm should be used to look up items in a large dictionary, however hashing routines are not provided in the standard library.
- Output:
B ?
zkl
<lang zkl>zkl: D("one",1, "two",2, "three",3) D(two:2,three:3,one:1)
zkl: Dictionary("one",1, "two",2, "three",3) D(two:2,three:3,one:1)
zkl: T("one",1, "two",2, "three",3).toDictionary() D(two:2,three:3,one:1)</lang>
- Programming Tasks
- Basic language learning
- Data Structures
- ActionScript
- Ada
- Aikido
- Aime
- ALGOL 68
- Apex
- APL
- App Inventor
- AutoHotkey
- AWK
- Babel
- BASIC256
- Batch File
- BBC BASIC
- Bracmat
- Brat
- C
- C++
- C sharp
- Ceylon
- Chapel
- Clojure
- ColdFusion
- Common Lisp
- Component Pascal
- D
- Dao
- Delphi
- E
- EchoLisp
- Elena
- Elixir
- Emacs Lisp
- Erlang
- F Sharp
- Factor
- Fantom
- Forth
- Forth Foundation Library
- Go
- Groovy
- Harbour
- Haskell
- Icon
- Unicon
- Inform 7
- Ioke
- J
- Java
- JavaScript
- Jq
- Julia
- K
- Kotlin
- Lang5
- Lasso
- LFE
- Liberty BASIC
- LiveCode
- Logo
- Lua
- Maple
- Mathematica
- Wolfram Language
- MATLAB
- Octave
- Maxima
- Nemerle
- NetRexx
- Nim
- Oberon-2
- Objeck
- Objective-C
- OCaml
- OoRexx
- OxygenBasic
- Oz
- PARI/GP
- Perl
- Perl 6
- Phix
- PHP
- PicoLisp
- PL/I
- PL/SQL
- Pop11
- PostScript
- Potion
- PowerShell
- Prolog
- PureBasic
- Python
- R
- Racket
- Raven
- Retro
- REXX
- RLaB
- Ruby
- Rust
- Sather
- Scala
- Scheme
- Seed7
- Sidef
- Slate
- Smalltalk
- SNOBOL4
- SQL
- Swift
- Tcl
- Toka
- UNIX Shell
- UnixPipes
- Vala
- Gee
- Vim Script
- Visual FoxPro
- Wart
- XPL0
- Zkl
- Applesoft BASIC/Omit
- Bc/Omit
- Brainf***/Omit
- Dc/Omit
- GUISS/Omit
- Integer BASIC/Omit
- TI-83 BASIC/Omit
- TI-89 BASIC/Omit