Associative array/Creation: Difference between revisions

mNo edit summary
 
(494 intermediate revisions by more than 100 users not shown)
Line 1:
[[Category:Data Structures]]
{{task}}
{{task|Basic language learning}}
{{Array operation}}
;Task:
The goal is to create an [[associative array]] (also known as a dictionary, map, or hash).
 
In this task, the goal is to create an [[associative array]].
 
Related tasks:
==[[C plus plus|C++]]==
* [[Associative arrays/Iteration]]
[[Category:C plus plus]]
* [[Hash from two arrays]]
'''Compiler:''' g++ 4.0.2
 
 
#include <map>
{{Template:See also lists}}
#include <string>
<br><br>
#include <iostream>
 
#include <ostream>
=={{header|11l}}==
<syntaxhighlight lang="11l">V dict = [‘key1’ = 1, ‘key2’ = 2]
V value2 = dict[‘key2’]</syntaxhighlight>
 
=={{header|8th}}==
8th has 'maps' as built-in data types, and can use JSON to describe them:
<syntaxhighlight lang="forth">
{ "one" : 1, "two" : "bad" }
</syntaxhighlight>
Alternatively, they can be created in code:
<syntaxhighlight lang="forth">
m:new "one" 1 m:! "two" "bad" m:!
</syntaxhighlight>
=={{header|AArch64 Assembly}}==
{{works with|as|Raspberry Pi 3B version Buster 64 bits <br> or android 64 bits with application Termux }}
<syntaxhighlight lang="aarch64 assembly">
/* ARM assembly AARCH64 Raspberry PI 3B or android 64 bits */
/* program hashmap64.s */
 
/*******************************************/
/* Constantes file */
/*******************************************/
/* for this file see task include a file in language AArch64 assembly*/
.include "../includeConstantesARM64.inc"
.equ MAXI, 10
.equ HEAPSIZE,20000
.equ LIMIT, 10 // key characters number for compute hash
.equ COEFF, 80 // filling rate 80 = 80%
 
 
/*******************************************/
/* Structures */
/********************************************/
/* structure hashMap */
.struct 0
hash_count: // stored values counter
.struct hash_count + 8
hash_key: // key
.struct hash_key + (8 * MAXI)
hash_data: // data
.struct hash_data + (8 * MAXI)
hash_fin:
/*********************************/
/* Initialized data */
/*********************************/
.data
szMessFin: .asciz "End program.\n"
szCarriageReturn: .asciz "\n"
szMessNoP: .asciz "Key not found !!!\n"
szKey1: .asciz "one"
szData1: .asciz "Ceret"
szKey2: .asciz "two"
szData2: .asciz "Maureillas"
szKey3: .asciz "three"
szData3: .asciz "Le Perthus"
szKey4: .asciz "four"
szData4: .asciz "Le Boulou"
 
.align 4
iptZoneHeap: .quad sZoneHeap // start heap address
iptZoneHeapEnd: .quad sZoneHeap + HEAPSIZE // end heap address
/*********************************/
/* UnInitialized data */
/*********************************/
.bss
tbHashMap1: .skip hash_fin // hashmap
sZoneHeap: .skip HEAPSIZE // heap
/*********************************/
/* code section */
/*********************************/
.text
.global main
main: // entry of program
ldr x0,qAdrtbHashMap1
bl hashInit // init hashmap
ldr x0,qAdrtbHashMap1
ldr x1,qAdrszKey1 // store key one
ldr x2,qAdrszData1
bl hashInsert
cmp x0,#0 // error ?
bne 100f
ldr x0,qAdrtbHashMap1
ldr x1,qAdrszKey2 // store key two
ldr x2,qAdrszData2
bl hashInsert
cmp x0,#0
bne 100f
ldr x0,qAdrtbHashMap1
ldr x1,qAdrszKey3 // store key three
ldr x2,qAdrszData3
bl hashInsert
cmp x0,#0
bne 100f
ldr x0,qAdrtbHashMap1
ldr x1,qAdrszKey4 // store key four
ldr x2,qAdrszData4
bl hashInsert
cmp x0,#0
bne 100f
ldr x0,qAdrtbHashMap1
ldr x1,qAdrszKey2 // remove key two
bl hashRemoveKey
cmp x0,#0
bne 100f
ldr x0,qAdrtbHashMap1
ldr x1,qAdrszKey1 // search key one
bl searchKey
cmp x0,#-1
beq 1f
bl affichageMess
ldr x0,qAdrszCarriageReturn
bl affichageMess
b 2f
1:
ldr x0,qAdrszMessNoP
bl affichageMess
2:
ldr x0,qAdrtbHashMap1
ldr x1,qAdrszKey2 // search key two
bl searchKey
cmp x0,#-1
beq 3f
bl affichageMess
ldr x0,qAdrszCarriageReturn
bl affichageMess
b 4f
3:
ldr x0,qAdrszMessNoP
bl affichageMess
4:
ldr x0,qAdrtbHashMap1
ldr x1,qAdrszKey4 // search key four
bl searchKey
cmp x0,#-1
beq 5f
bl affichageMess
ldr x0,qAdrszCarriageReturn
bl affichageMess
b 6f
5:
ldr x0,qAdrszMessNoP
bl affichageMess
6:
ldr x0,qAdrszMessFin
bl affichageMess
100: // standard end of the program
mov x0, #0 // return code
mov x8, #EXIT // request to exit program
svc #0 // perform the system call
qAdrszCarriageReturn: .quad szCarriageReturn
qAdrszMessFin: .quad szMessFin
qAdrtbHashMap1: .quad tbHashMap1
qAdrszKey1: .quad szKey1
qAdrszData1: .quad szData1
qAdrszKey2: .quad szKey2
qAdrszData2: .quad szData2
qAdrszKey3: .quad szKey3
qAdrszData3: .quad szData3
qAdrszKey4: .quad szKey4
qAdrszData4: .quad szData4
qAdrszMessNoP: .quad szMessNoP
/***************************************************/
/* init hashMap */
/***************************************************/
// x0 contains address to hashMap
hashInit:
stp x1,lr,[sp,-16]! // save registres
stp x2,x3,[sp,-16]! // save registres
mov x1,#0
mov x2,#0
str x2,[x0,#hash_count] // init counter
add x0,x0,#hash_key // start zone key/value
1:
lsl x3,x1,#3
add x3,x3,x0
str x2,[x3,#hash_key]
str x2,[x3,#hash_data]
add x1,x1,#1
cmp x1,#MAXI
blt 1b
100:
ldp x2,x3,[sp],16 // restaur des 2 registres
ldp x1,lr,[sp],16 // restaur des 2 registres
ret
/***************************************************/
/* insert key/datas */
/***************************************************/
// x0 contains address to hashMap
// x1 contains address to key
// x2 contains address to datas
hashInsert:
stp x1,lr,[sp,-16]! // save registres
stp x2,x3,[sp,-16]! // save registres
stp x4,x5,[sp,-16]! // save registres
stp x6,x7,[sp,-16]! // save registres
mov x6,x0 // save address
bl hashIndex // search void key or identical key
cmp x0,#0 // error ?
blt 100f
ldr x3,qAdriptZoneHeap
ldr x3,[x3]
ldr x7,qAdriptZoneHeapEnd
ldr x7,[x7]
sub x7,x7,#50
lsl x0,x0,#3 // 8 bytes
add x5,x6,#hash_key // start zone key/value
ldr x4,[x5,x0]
cmp x4,#0 // key already stored ?
bne 1f
ldr x4,[x6,#hash_count] // no -> increment counter
add x4,x4,#1
cmp x4,#(MAXI * COEFF / 100)
bge 98f
str x4,[x6,#hash_count]
1:
str x3,[x5,x0] // store heap key address in hashmap
mov x4,#0
2: // copy key loop in heap
ldrb w5,[x1,x4]
strb w5,[x3,x4]
cmp w5,#0
add x4,x4,#1
bne 2b
add x3,x3,x4
cmp x3,x7
bge 99f
add x1,x6,#hash_data
str x3,[x1,x0] // store heap data address in hashmap
mov x4,#0
3: // copy data loop in heap
ldrb w5,[x2,x4]
strb w5,[x3,x4]
cmp w5,#0
add x4,x4,#1
bne 3b
add x3,x3,x4
cmp x3,x7
bge 99f
ldr x0,qAdriptZoneHeap
str x3,[x0] // new heap address
mov x0,#0 // insertion OK
b 100f
98: // error hashmap
adr x0,szMessErrInd
bl affichageMess
mov x0,#-1
b 100f
99: // error heap
adr x0,szMessErrHeap
bl affichageMess
mov x0,#-1
100:
ldp x6,x7,[sp],16 // restaur des 2 registres
ldp x4,x5,[sp],16 // restaur des 2 registres
ldp x2,x3,[sp],16 // restaur des 2 registres
ldp x1,lr,[sp],16 // restaur des 2 registres
ret
szMessErrInd: .asciz "Error : HashMap size Filling rate Maxi !!\n"
szMessErrHeap: .asciz "Error : Heap size Maxi !!\n"
.align 4
qAdriptZoneHeap: .quad iptZoneHeap
qAdriptZoneHeapEnd: .quad iptZoneHeapEnd
/***************************************************/
/* search void index in hashmap */
/***************************************************/
// x0 contains hashMap address
// x1 contains key address
hashIndex:
stp x1,lr,[sp,-16]! // save registres
stp x2,x3,[sp,-16]! // save registres
stp x4,x5,[sp,-16]! // save registres
add x4,x0,#hash_key
mov x2,#0 // index
mov x3,#0 // characters sum
1: // loop to compute characters sum
ldrb w0,[x1,x2]
cmp w0,#0 // string end ?
beq 2f
add x3,x3,x0 // add to sum
add x2,x2,#1
cmp x2,#LIMIT
blt 1b
2:
mov x5,x1 // save key address
mov x0,x3
mov x1,#MAXI
udiv x2,x0,x1
msub x3,x2,x1,x0 // compute remainder -> x3
mov x1,x5 // key address
3:
ldr x0,[x4,x3,lsl #3] // loak key for computed index
cmp x0,#0 // void key ?
beq 4f
bl comparStrings // identical key ?
cmp x0,#0
beq 4f // yes
add x3,x3,#1 // no search next void key
cmp x3,#MAXI // maxi ?
csel x3,xzr,x3,ge // restart to index 0
b 3b
4:
mov x0,x3 // return index void array or key equal
100:
ldp x4,x5,[sp],16 // restaur des 2 registres
ldp x2,x3,[sp],16 // restaur des 2 registres
ldp x1,lr,[sp],16 // restaur des 2 registres
ret
 
/***************************************************/
/* search key in hashmap */
/***************************************************/
// x0 contains hash map address
// x1 contains key address
searchKey:
stp x1,lr,[sp,-16]! // save registres
stp x2,x3,[sp,-16]! // save registres
mov x2,x0
bl hashIndex
lsl x0,x0,#3
add x1,x0,#hash_key
ldr x1,[x2,x1]
cmp x1,#0
beq 2f
add x1,x0,#hash_data
ldr x0,[x2,x1]
b 100f
2:
mov x0,#-1
100:
ldp x2,x3,[sp],16 // restaur des 2 registres
ldp x1,lr,[sp],16 // restaur des 2 registres
ret
/***************************************************/
/* remove key in hashmap */
/***************************************************/
// x0 contains hash map address
// x1 contains key address
hashRemoveKey:
stp x1,lr,[sp,-16]! // save registres
stp x2,x3,[sp,-16]! // save registres
mov x2,x0
bl hashIndex
lsl x0,x0,#3
add x1,x0,#hash_key
ldr x3,[x2,x1]
cmp x3,#0
beq 2f
str xzr,[x2,x1] // raz key address
add x1,x0,#hash_data
str xzr,[x2,x1] // raz datas address
mov x0,0
b 100f
2:
adr x0,szMessErrRemove
bl affichageMess
mov x0,#-1
100:
ldp x2,x3,[sp],16 // restaur des 2 registres
ldp x1,lr,[sp],16 // restaur des 2 registres
ret
szMessErrRemove: .asciz "\033[31mError remove key !!\033[0m\n"
.align 4
/************************************/
/* Strings case sensitive comparisons */
/************************************/
/* x0 et x1 contains the address of strings */
/* return 0 in x0 if equals */
/* return -1 if string x0 < string x1 */
/* return 1 if string x0 > string x1 */
comparStrings:
stp x1,lr,[sp,-16]! // save registres
stp x2,x3,[sp,-16]! // save registres
stp x4,x5,[sp,-16]! // save registres
mov x2,#0 // characters counter
1:
ldrb w3,[x0,x2] // byte string 1
ldrb w4,[x1,x2] // byte string 2
cmp w3,w4
blt 2f
bgt 3f
cmp w3,#0 // 0 end string ?
beq 4f
add x2,x2,#1 // else add 1 in counter
b 1b // and loop
2:
mov x0,#-1 // smaller
b 100f
3:
mov x0,#1 // greather
b 100f
4:
mov x0,#0 // equals
100:
ldp x4,x5,[sp],16 // restaur des 2 registres
ldp x2,x3,[sp],16 // restaur des 2 registres
ldp x1,lr,[sp],16 // restaur des 2 registres
ret
/********************************************************/
/* File Include fonctions */
/********************************************************/
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"
 
</syntaxhighlight>
 
=={{header|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.
<syntaxhighlight 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"</syntaxhighlight>
''Note: The Object only supports String keys. To use an object as a key, try the flash.utils.Dictionary class.''
 
=={{header|Ada}}==
{{works with|GNAT|GPL 2007}}
<syntaxhighlight 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;
int main()
Color_Cursor : Cursor;
{
Success : Boolean;
// This is an associative array which maps strings to ints
Value : Integer;
typedef std::map<std::string, int> colormap_t;
begin
colormap_t colormap;
 
-- 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;</syntaxhighlight>
 
=={{header|Aikido}}==
Aikido provides a native <em>map</em> for associative arrays. You can create them using a map literal and you can insert and remove items on the fly.
<syntaxhighlight 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"]
 
 
</syntaxhighlight>
 
=={{header|Aime}}==
Aime records are heterogenous associative arrays. No creation procedure is required, declaration is fine.
<syntaxhighlight lang="aime">record r;</syntaxhighlight>
<syntaxhighlight 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</syntaxhighlight>
 
=={{header|ALGOL 68}}==
{{trans|C++}}
 
{{works with|ALGOL 68|Revision 1 - no extensions to language used}}
 
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-1.18.0/algol68g-1.18.0-9h.tiny.el5.centos.fc11.i386.rpm/download 1.18.0-9h.tiny]}}
{{wont work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d] - due to extensive use of FORMATted transput}}
<syntaxhighlight 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$))
 
)</syntaxhighlight>
{{out}}
<pre>
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)
</pre>
 
=={{header|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:
<syntaxhighlight 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') );</syntaxhighlight>
 
Creating a new map of String to String with values initialized:
<syntaxhighlight 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') );</syntaxhighlight>
 
=={{header|APL}}==
{{works with|Dyalog APL}}
<syntaxhighlight 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
</syntaxhighlight>
 
{{works with|GNU APL}}
<syntaxhighlight lang="apl">
⍝ Assign some names
X.this←'that'
X.foo←88
⍝ Access the names
X.this
that
 
⍝ ..or access via 'array index' syntax
X['this']
that
⍝ Or do it the array way
X.(foo)
88
 
⍝ GNU APL does not support multiple assoc. array indices however
X.(foo this)
VALUE ERROR
X.(foo this)
^
 
(sales.prices sales.quantities) ← (100 98.4 103.4 110.16) (10 12 8 10)
sales.revenue ← sales.prices +.× sales.quantities
sales.revenue
4109.6
</syntaxhighlight>
 
=={{header|App Inventor}}==
Associative arrays in App Inventor are lists of ''key:value'' 'pairs'.<br>
When a list is organized as pairs, the '''lookup in pairs''' block can be used to retrieve an associated value from a key name.<br>
[https://lh3.googleusercontent.com/-Cxw_-XGMRyM/UutOX1bEH9I/AAAAAAAAJ9g/MZotfuSEziY/s1600/CreateIterateLookup.PNG '''<VIEW BLOCKS AND ANDROID APP>''']
 
=={{header|ARM Assembly}}==
{{works with|as|Raspberry Pi <br> or android 32 bits with application Termux}}
<syntaxhighlight lang="arm assembly">
/* ARM assembly Raspberry PI or android 32 bits */
/* program hashmap.s */
 
/* */
 
/* REMARK 1 : this program use routines in a include file
see task Include a file language arm assembly
for the routine affichageMess conversion10
see at end of this program the instruction include */
/* for constantes see task include a file in arm assembly */
/************************************/
/* Constantes */
/************************************/
.include "../constantes.inc"
.equ MAXI, 10 @ size hashmap
.equ HEAPSIZE,20000
.equ LIMIT, 10 @ key characters number for compute index
.equ COEFF, 80 @ filling rate 80 = 80%
 
 
/*******************************************/
/* Structures */
/********************************************/
/* structure hashMap */
.struct 0
hash_count: // stored values counter
.struct hash_count + 4
hash_key: // key
.struct hash_key + (4 * MAXI)
hash_data: // data
.struct hash_data + (4 * MAXI)
hash_fin:
/*********************************/
/* Initialized data */
/*********************************/
.data
szMessFin: .asciz "End program.\n"
szCarriageReturn: .asciz "\n"
szMessNoP: .asciz "Key not found !!!\n"
szKey1: .asciz "one"
szData1: .asciz "Ceret"
szKey2: .asciz "two"
szData2: .asciz "Maureillas"
szKey3: .asciz "three"
szData3: .asciz "Le Perthus"
szKey4: .asciz "four"
szData4: .asciz "Le Boulou"
 
.align 4
iptZoneHeap: .int sZoneHeap // start heap address
iptZoneHeapEnd: .int sZoneHeap + HEAPSIZE // end heap address
/*********************************/
/* UnInitialized data */
/*********************************/
.bss
//sZoneConv: .skip 24
tbHashMap1: .skip hash_fin @ hashmap
sZoneHeap: .skip HEAPSIZE @ heap
/*********************************/
/* code section */
/*********************************/
.text
.global main
main: @ entry of program
ldr r0,iAdrtbHashMap1
// First, populate it with some values
bl hashInit @ init hashmap
colormap["red"] = 0xff0000;
ldr r0,iAdrtbHashMap1
colormap["green"] = 0x00ff00;
ldr r1,iAdrszKey1 @ store key one
colormap["blue"] = 0x0000ff;
ldr r2,iAdrszData1
colormap["my favourite color"] = 0x00ffff;
bl hashInsert
cmp r0,#0 @ error ?
bne 100f
ldr r0,iAdrtbHashMap1
ldr r1,iAdrszKey2 @ store key two
ldr r2,iAdrszData2
bl hashInsert
cmp r0,#0
bne 100f
ldr r0,iAdrtbHashMap1
ldr r1,iAdrszKey3 @ store key three
ldr r2,iAdrszData3
bl hashInsert
cmp r0,#0
bne 100f
ldr r0,iAdrtbHashMap1
ldr r1,iAdrszKey4 @ store key four
ldr r2,iAdrszData4
bl hashInsert
cmp r0,#0
bne 100f
ldr r0,iAdrtbHashMap1
// then, get some values out
ldr r1,iAdrszKey2 @ remove key two
int color = colormap["green"]; // color gets 0x00ff00
bl hashRemoveKey
color = colormap["black"]; // accessing unassigned values assigns them to 0
cmp r0,#0
bne 100f
ldr r0,iAdrtbHashMap1
// get some value out without accidentally inserting new ones
ldr r1,iAdrszKey1 @ search key
colormap_t::iterator i = colormap.find("green");
bl searchKey
if (i == colormap.end())
{cmp r0,#-1
beq 1f
std::cerr << "color not found!\n";
bl affichageMess
}
ldr r0,iAdrszCarriageReturn
else
bl affichageMess
{
b 2f
color = i->second;
1:
}
ldr r0,iAdrszMessNoP
bl affichageMess
2:
ldr r0,iAdrtbHashMap1
ldr r1,iAdrszKey2
bl searchKey
cmp r0,#-1
beq 3f
bl affichageMess
ldr r0,iAdrszCarriageReturn
bl affichageMess
b 4f
3:
ldr r0,iAdrszMessNoP
bl affichageMess
4:
ldr r0,iAdrtbHashMap1
ldr r1,iAdrszKey4
bl searchKey
cmp r0,#-1
beq 5f
bl affichageMess
ldr r0,iAdrszCarriageReturn
bl affichageMess
b 6f
5:
ldr r0,iAdrszMessNoP
bl affichageMess
6:
ldr r0,iAdrszMessFin
bl affichageMess
100: @ standard end of the program
mov r0, #0 @ return code
mov r7, #EXIT @ request to exit program
svc #0 @ perform the system call
iAdrszCarriageReturn: .int szCarriageReturn
iAdrszMessFin: .int szMessFin
iAdrtbHashMap1: .int tbHashMap1
iAdrszKey1: .int szKey1
iAdrszData1: .int szData1
iAdrszKey2: .int szKey2
iAdrszData2: .int szData2
iAdrszKey3: .int szKey3
iAdrszData3: .int szData3
iAdrszKey4: .int szKey4
iAdrszData4: .int szData4
iAdrszMessNoP: .int szMessNoP
/***************************************************/
/* init hashMap */
/***************************************************/
// r0 contains address to hashMap
hashInit:
push {r1-r3,lr} @ save registers
mov r1,#0
mov r2,#0
str r2,[r0,#hash_count] @ init counter
add r0,r0,#hash_key @ start zone key/value
1:
lsl r3,r1,#3
add r3,r3,r0
str r2,[r3,#hash_key]
str r2,[r3,#hash_data]
add r1,r1,#1
cmp r1,#MAXI
blt 1b
100:
pop {r1-r3,pc} @ restaur registers
/***************************************************/
/* insert key/datas */
/***************************************************/
// r0 contains address to hashMap
// r1 contains address to key
// r2 contains address to datas
hashInsert:
push {r1-r8,lr} @ save registers
mov r6,r0 @ save address
bl hashIndex @ search void key or identical key
cmp r0,#0 @ error ?
blt 100f
ldr r3,iAdriptZoneHeap
// Now I changed my mind about my favourite color, so change it
ldr r3,[r3]
colormap["my favourite color"] = 0x337733;
ldr r8,iAdriptZoneHeapEnd
ldr r8,[r8]
sub r8,r8,#50
lsl r0,r0,#2 @ 4 bytes
add r7,r6,#hash_key @ start zone key/value
ldr r4,[r7,r0]
cmp r4,#0 @ key already stored ?
bne 1f
ldr r4,[r6,#hash_count] @ no -> increment counter
add r4,r4,#1
cmp r4,#(MAXI * COEFF / 100)
bge 98f
str r4,[r6,#hash_count]
1:
str r3,[r7,r0]
mov r4,#0
2: @ copy key loop in heap
ldrb r5,[r1,r4]
strb r5,[r3,r4]
cmp r5,#0
add r4,r4,#1
bne 2b
add r3,r3,r4
cmp r3,r8
bge 99f
add r7,r6,#hash_data
str r3,[r7,r0]
mov r4,#0
3: @ copy data loop in heap
ldrb r5,[r2,r4]
strb r5,[r3,r4]
cmp r5,#0
add r4,r4,#1
bne 3b
add r3,r3,r4
cmp r3,r8
bge 99f
ldr r0,iAdriptZoneHeap
str r3,[r0] @ new heap address
mov r0,#0 @ insertion OK
// print out all defined colors
b 100f
for (colormap_t::iterator i = colormap.begin(); i != colormap.end(); ++i)
98: @ error hashmap
std::cerr << "colormap[\"" << i->first << "\"] = 0x" << std::hex << i->second << "\n";
adr r0,szMessErrInd
bl affichageMess
mov r0,#-1
b 100f
99: @ error heap
adr r0,szMessErrHeap
bl affichageMess
mov r0,#-1
100:
pop {r1-r8,lr} @ restaur registers
bx lr @ return
szMessErrInd: .asciz "Error : HashMap size Filling rate Maxi !!\n"
szMessErrHeap: .asciz "Error : Heap size Maxi !!\n"
.align 4
iAdriptZoneHeap: .int iptZoneHeap
iAdriptZoneHeapEnd: .int iptZoneHeapEnd
/***************************************************/
/* search void index in hashmap */
/***************************************************/
// r0 contains hashMap address
// r1 contains key address
hashIndex:
push {r1-r4,lr} @ save registers
add r4,r0,#hash_key
mov r2,#0 @ index
mov r3,#0 @ characters sum
1: @ loop to compute characters sum
ldrb r0,[r1,r2]
cmp r0,#0 @ string end ?
beq 2f
add r3,r3,r0 @ add to sum
add r2,r2,#1
cmp r2,#LIMIT
blt 1b
2:
mov r5,r1 @ save key address
mov r0,r3
mov r1,#MAXI
bl division @ compute remainder -> r3
mov r1,r5 @ key address
3:
ldr r0,[r4,r3,lsl #2] @ loak key for computed index
cmp r0,#0 @ void key ?
beq 4f
bl comparStrings @ identical key ?
cmp r0,#0
beq 4f @ yes
add r3,r3,#1 @ no search next void key
cmp r3,#MAXI @ maxi ?
movge r3,#0 @ restart to index 0
b 3b
4:
mov r0,r3 @ return index void array or key equal
100:
pop {r1-r4,pc} @ restaur registers
 
/***************************************************/
/* search key in hashmap */
/***************************************************/
// r0 contains hash map address
// r1 contains key address
searchKey:
push {r1-r2,lr} @ save registers
mov r2,r0
bl hashIndex
lsl r0,r0,#2
add r1,r0,#hash_key
ldr r1,[r2,r1]
cmp r1,#0
moveq r0,#-1
beq 100f
add r1,r0,#hash_data
ldr r0,[r2,r1]
100:
pop {r1-r2,pc} @ restaur registers
/***************************************************/
/* remove key in hashmap */
/***************************************************/
// r0 contains hash map address
// r1 contains key address
hashRemoveKey: @ INFO: hashRemoveKey
push {r1-r3,lr} @ save registers
mov r2,r0
bl hashIndex
lsl r0,r0,#2
add r1,r0,#hash_key
ldr r3,[r2,r1]
cmp r3,#0
beq 2f
add r3,r2,r1
mov r1,#0 @ raz key address
str r1,[r3]
add r1,r0,#hash_data
add r3,r2,r1
mov r1,#0
str r1,[r3] @ raz datas address
mov r0,#0
b 100f
2:
adr r0,szMessErrRemove
bl affichageMess
mov r0,#-1
100:
pop {r1-r3,pc} @ restaur registers
szMessErrRemove: .asciz "\033[31mError remove key !!\033[0m\n"
.align 4
/************************************/
/* Strings case sensitive comparisons */
/************************************/
/* r0 et r1 contains the address of strings */
/* return 0 in r0 if equals */
/* return -1 if string r0 < string r1 */
/* return 1 if string r0 > string r1 */
comparStrings:
push {r1-r4} @ save des registres
mov r2,#0 @ characters counter
1:
ldrb r3,[r0,r2] @ byte string 1
ldrb r4,[r1,r2] @ byte string 2
cmp r3,r4
movlt r0,#-1 @ smaller
movgt r0,#1 @ greather
bne 100f @ not equals
cmp r3,#0 @ 0 end string ?
moveq r0,#0 @ equals
beq 100f @ end string
add r2,r2,#1 @ else add 1 in counter
b 1b @ and loop
100:
pop {r1-r4}
bx lr
/***************************************************/
/* ROUTINES INCLUDE */
/***************************************************/
.include "../affichage.inc"
 
</syntaxhighlight>
=={{header|Arturo}}==
 
<syntaxhighlight lang="rebol">; create a dictionary
d: #[
name: "john"
surname: "doe"
age: 34
]
 
print d</syntaxhighlight>
 
{{out}}
 
<pre>[name:john surname:doe age:34]</pre>
 
=={{header|ATS}}==
 
ATS, like many languages, does not have high level stuff such as maps built into the language itself, so library support or one's own code is what one needs.
 
In the following, ''persistence'' means that past values of the map are retained, if they continue to have references to them. This property sometimes is called ''immutability'', but I feel that term implies too much.
 
=== Persistent association lists ===
The following implementation includes set, get, and delete, and also "generators", which are like iterators except they are closures rather than regular objects.
<syntaxhighlight lang="ats">(*------------------------------------------------------------------*)
 
#define ATS_DYNLOADFLAG 0
 
#include "share/atspre_staload.hats"
 
(*------------------------------------------------------------------*)
(* Interface *)
 
(* You can put the interface in a .sats file. You will have to remove
the word "extern". *)
 
typedef alist_t (key_t : t@ype+,
data_t : t@ype+,
size : int) =
list (@(key_t, data_t), size)
typedef alist_t (key_t : t@ype+,
data_t : t@ype+) =
[size : int]
alist_t (key_t, data_t, size)
 
extern prfun
lemma_alist_t_param :
{size : int} {key_t : t@ype} {data_t : t@ype}
alist_t (key_t, data_t, size) -<prf> [0 <= size] void
 
extern fun {key_t : t@ype} (* Implement key equality with this. *)
alist_t$key_eq : (key_t, key_t) -<> bool
 
(* alist_t_nil: create an empty association list. *)
extern fun
alist_t_nil :
{key_t : t@ype} {data_t : t@ype}
() -<> alist_t (key_t, data_t, 0)
 
(* alist_t_set: add an association, deleting old associations with an
equal key. *)
extern fun {key_t : t@ype}
{data_t : t@ype}
alist_t_set {size : int}
(alst : alist_t (key_t, data_t, size),
key : key_t,
data : data_t) :<>
[sz : int | 1 <= sz]
alist_t (key_t, data_t, sz)
 
(* alist_t_get: find an association and return its data, if
present. *)
extern fun {key_t : t@ype}
{data_t : t@ype}
alist_t_get {size : int}
(alst : alist_t (key_t, data_t, size),
key : key_t) :<>
Option data_t
 
(* alist_t_delete: delete all associations with key. *)
extern fun {key_t : t@ype}
{data_t : t@ype}
alist_t_delete {size : int}
(alst : alist_t (key_t, data_t, size),
key : key_t ) :<>
[sz : int | 0 <= sz]
alist_t (key_t, data_t, sz)
 
(* alist_t_make_pairs_generator: make a closure that returns
the association pairs, one by one. This is a form of iterator.
Analogous generators can be made for the keys or data values
alone. *)
extern fun {key_t : t@ype}
{data_t : t@ype}
alist_t_make_pairs_generator
{size : int}
(alst : alist_t (key_t, data_t, size)) :<!wrt>
() -<cloref,!refwrt> Option @(key_t, data_t)
 
(*------------------------------------------------------------------*)
(* Implementation *)
 
#define NIL list_nil ()
#define :: list_cons
 
primplement
lemma_alist_t_param alst =
lemma_list_param alst
 
implement
alist_t_nil () =
NIL
 
implement {key_t} {data_t}
alist_t_set (alst, key, data) =
@(key, data) :: alist_t_delete (alst, key)
 
implement {key_t} {data_t}
alist_t_get (alst, key) =
let
fun
loop {n : nat}
.<n>. (* <-- proof of termination *)
(lst : alist_t (key_t, data_t, n)) :<>
Option data_t =
case+ lst of
| NIL => None ()
| head :: tail =>
if alist_t$key_eq (key, head.0) then
Some (head.1)
else
loop tail
 
prval _ = lemma_alist_t_param alst
in
loop alst
end
 
implement {key_t} {data_t}
alist_t_delete (alst, key) =
let
fun
delete {n : nat}
.<n>. (* <-- proof of termination *)
(lst : alist_t (key_t, data_t, n)) :<>
[m : nat] alist_t (key_t, data_t, m) =
(* This implementation is *not* tail recursive, but has the
minor advantage of preserving the order of entries without
doing a lot of work. *)
case+ lst of
| NIL => lst
| head :: tail =>
if alist_t$key_eq (key, head.0) then
delete tail
else
head :: delete tail
 
prval _ = lemma_alist_t_param alst
in
delete alst
end
 
implement {key_t} {data_t}
alist_t_make_pairs_generator alst =
let
typedef alist_t = [sz : int] alist_t (key_t, data_t, sz)
 
val alst_ref = ref alst
 
(* Cast the ref to a pointer so it can be enclosed in the
closure. *)
val alst_ptr = $UNSAFE.castvwtp0{ptr} alst_ref
in
lam () =>
let
val alst_ref = $UNSAFE.castvwtp0{ref alist_t} alst_ptr
in
case+ !alst_ref of
| NIL => None ()
| head :: tail =>
begin
!alst_ref := tail;
(* For a keys generator, change the following line to
"Some (head.0)"; for a data values generator, change
it to "Some (head.1)". *)
Some head
end
end
end
 
(*------------------------------------------------------------------*)
(* Demonstration program *)
 
implement
alist_t$key_eq<string> (s, t) =
s = t
 
typedef s2i_alist_t = alist_t (string, int)
 
fn
s2i_alist_t_set (map : s2i_alist_t,
key : string,
data : int) :<> s2i_alist_t =
alist_t_set<string><int> (map, key, data)
 
fn
s2i_alist_t_set_ref (map : &s2i_alist_t >> _,
key : string,
data : int) :<!wrt> void =
(* Update a reference to a persistent alist. *)
map := s2i_alist_t_set (map, key, data)
 
fn
s2i_alist_t_get (map : s2i_alist_t,
key : string) :<> Option int =
alist_t_get<string><int> (map, key)
 
extern fun {} (* {} = a template without template parameters *)
s2i_alist_t_get_dflt$dflt :<> () -> int
fn {} (* {} = a template without template parameters *)
s2i_alist_t_get_dflt (map : s2i_alist_t,
key : string) : int =
case+ s2i_alist_t_get (map, key) of
| Some x => x
| None () => s2i_alist_t_get_dflt$dflt<> ()
 
overload [] with s2i_alist_t_set_ref
overload [] with s2i_alist_t_get_dflt
 
implement
main0 () =
let
implement s2i_alist_t_get_dflt$dflt<> () = 0
var map = alist_t_nil ()
var gen : () -<cloref1> @(string, int)
var pair : Option @(string, int)
in
map["one"] := 1;
map["two"] := 2;
map["three"] := 3;
println! ("map[\"one\"] = ", map["one"]);
println! ("map[\"two\"] = ", map["two"]);
println! ("map[\"three\"] = ", map["three"]);
println! ("map[\"four\"] = ", map["four"]);
gen := alist_t_make_pairs_generator<string><int> map;
for (pair := gen (); option_is_some pair; pair := gen ())
println! (pair)
end
 
(*------------------------------------------------------------------*)</syntaxhighlight>
 
{{out}}
<pre>$ patscc -O2 -DATS_MEMALLOC_GCBDW association_lists-postiats.dats -lgc && ./a.out
map["one"] = 1
map["two"] = 2
map["three"] = 3
map["four"] = 0
Some((three, 3))
Some((two, 2))
Some((one, 1))</pre>
 
=== Persistent hashmaps based on AVL trees ===
{{trans|Scheme}}
{{libheader|xxHash}}
The following implementation includes set and get, and also "generators", which are like iterators except they are closures rather than regular objects. A delete function could easily be added.
 
To run this demonstration you need the [http://www.xxhash.net xxHash] C library. I have written an implementation of SpookyHash in ATS, but using a C library is fine, and requires less ATS code.
 
Because the hash table is an AVL tree, performance will tend to be logarithmic. This assumes a good hash function, of course. With a bad hash function, performance may be linear.
 
<syntaxhighlight lang="ats">(*------------------------------------------------------------------*)
 
#define ATS_DYNLOADFLAG 0
 
#include "share/atspre_staload.hats"
 
(*------------------------------------------------------------------*)
(* String hashing using XXH3_64bits from the xxHash suite. *)
 
#define ATS_EXTERN_PREFIX "hashmaps_postiats_"
 
%{^ /* Embedded C code. */
 
#include <xxhash.h>
 
ATSinline() atstype_uint64
hashmaps_postiats_mem_hash (atstype_ptr data, atstype_size len)
{
return (atstype_uint64) XXH3_64bits (data, len);
}
 
%}
 
extern fn mem_hash : (ptr, size_t) -<> uint64 = "mac#%"
 
fn
string_hash (s : string) :<> uint64 =
let
val len = string_length s
in
mem_hash ($UNSAFE.cast{ptr} s, len)
end
 
(*------------------------------------------------------------------*)
(* A trimmed down version of the AVL trees from the AVL Tree task. *)
 
datatype bal_t =
| bal_minus1
| bal_zero
| bal_plus1
 
datatype avl_t (key_t : t@ype+,
data_t : t@ype+,
size : int) =
| avl_t_nil (key_t, data_t, 0)
| {size_L, size_R : nat}
avl_t_cons (key_t, data_t, size_L + size_R + 1) of
(key_t, data_t, bal_t,
avl_t (key_t, data_t, size_L),
avl_t (key_t, data_t, size_R))
typedef avl_t (key_t : t@ype+,
data_t : t@ype+) =
[size : int] avl_t (key_t, data_t, size)
 
extern fun {key_t : t@ype}
avl_t$compare (u : key_t, v : key_t) :<> int
 
#define NIL avl_t_nil ()
#define CONS avl_t_cons
#define LNIL list_nil ()
#define :: list_cons
#define F false
#define T true
 
typedef fixbal_t = bool
 
prfn
lemma_avl_t_param {key_t : t@ype} {data_t : t@ype} {size : int}
(avl : avl_t (key_t, data_t, size)) :<prf>
[0 <= size] void =
case+ avl of NIL => () | CONS _ => ()
 
fn {}
minus_neg_bal (bal : bal_t) :<> bal_t =
case+ bal of
| bal_minus1 () => bal_plus1
| _ => bal_zero ()
 
fn {}
minus_pos_bal (bal : bal_t) :<> bal_t =
case+ bal of
| bal_plus1 () => bal_minus1
| _ => bal_zero ()
 
fn
avl_t_is_empty {key_t : t@ype} {data_t : t@ype} {size : int}
(avl : avl_t (key_t, data_t, size)) :<>
[b : bool | b == (size == 0)] bool b =
case+ avl of
| NIL => T
| CONS _ => F
 
fn
avl_t_isnot_empty {key_t : t@ype} {data_t : t@ype} {size : int}
(avl : avl_t (key_t, data_t, size)) :<>
[b : bool | b == (size <> 0)] bool b =
~avl_t_is_empty avl
 
fn {key_t : t@ype} {data_t : t@ype}
avl_t_search_ref {size : int}
(avl : avl_t (key_t, data_t, size),
key : key_t,
data : &data_t? >> opt (data_t, found),
found : &bool? >> bool found) :<!wrt>
#[found : bool] void =
let
fun
search (p : avl_t (key_t, data_t),
data : &data_t? >> opt (data_t, found),
found : &bool? >> bool found) :<!wrt,!ntm>
#[found : bool] void =
case+ p of
| NIL =>
{
prval _ = opt_none {data_t} data
val _ = found := F
}
| CONS (k, d, _, left, right) =>
begin
case+ avl_t$compare<key_t> (key, k) of
| cmp when cmp < 0 => search (left, data, found)
| cmp when cmp > 0 => search (right, data, found)
| _ =>
{
val _ = data := d
prval _ = opt_some {data_t} data
val _ = found := T
}
end
in
$effmask_ntm search (avl, data, found)
end
 
fn {key_t : t@ype} {data_t : t@ype}
avl_t_search_opt {size : int}
(avl : avl_t (key_t, data_t, size),
key : key_t) :<>
Option (data_t) =
let
var data : data_t?
var found : bool?
val _ = $effmask_wrt avl_t_search_ref (avl, key, data, found)
in
if found then
let
prval _ = opt_unsome data
in
Some {data_t} data
end
else
let
prval _ = opt_unnone data
in
None {data_t} ()
end
end
 
fn {key_t : t@ype} {data_t : t@ype}
avl_t_insert_or_replace {size : int}
(avl : avl_t (key_t, data_t, size),
key : key_t,
data : data_t) :<>
[sz : pos] (avl_t (key_t, data_t, sz), bool) =
let
fun
search {size : nat}
(p : avl_t (key_t, data_t, size),
fixbal : fixbal_t,
found : bool) :<!ntm>
[sz : pos]
(avl_t (key_t, data_t, sz), fixbal_t, bool) =
case+ p of
| NIL => (CONS (key, data, bal_zero, NIL, NIL), T, F)
| CONS (k, d, bal, left, right) =>
case+ avl_t$compare<key_t> (key, k) of
| cmp when cmp < 0 =>
let
val (p1, fixbal, found) = search (left, fixbal, found)
in
case+ (fixbal, bal) of
| (F, _) => (CONS (k, d, bal, p1, right), F, found)
| (T, bal_plus1 ()) =>
(CONS (k, d, bal_zero (), p1, right), F, found)
| (T, bal_zero ()) =>
(CONS (k, d, bal_minus1 (), p1, right), fixbal, found)
| (T, bal_minus1 ()) =>
let
val+ CONS (k1, d1, bal1, left1, right1) = p1
in
case+ bal1 of
| bal_minus1 () =>
let
val q = CONS (k, d, bal_zero (), right1, right)
val q1 = CONS (k1, d1, bal_zero (), left1, q)
in
(q1, F, found)
end
| _ =>
let
val p2 = right1
val- CONS (k2, d2, bal2, left2, right2) = p2
val q = CONS (k, d, minus_neg_bal bal2,
right2, right)
val q1 = CONS (k1, d1, minus_pos_bal bal2,
left1, left2)
val q2 = CONS (k2, d2, bal_zero (), q1, q)
in
(q2, F, found)
end
end
end
| cmp when cmp > 0 =>
let
val (p1, fixbal, found) = search (right, fixbal, found)
in
case+ (fixbal, bal) of
| (F, _) => (CONS (k, d, bal, left, p1), F, found)
| (T, bal_minus1 ()) =>
(CONS (k, d, bal_zero (), left, p1), F, found)
| (T, bal_zero ()) =>
(CONS (k, d, bal_plus1 (), left, p1), fixbal, found)
| (T, bal_plus1 ()) =>
let
val+ CONS (k1, d1, bal1, left1, right1) = p1
in
case+ bal1 of
| bal_plus1 () =>
let
val q = CONS (k, d, bal_zero (), left, left1)
val q1 = CONS (k1, d1, bal_zero (), q, right1)
in
(q1, F, found)
end
| _ =>
let
val p2 = left1
val- CONS (k2, d2, bal2, left2, right2) = p2
val q = CONS (k, d, minus_pos_bal bal2,
left, left2)
val q1 = CONS (k1, d1, minus_neg_bal bal2,
right2, right1)
val q2 = CONS (k2, d2, bal_zero (), q, q1)
in
(q2, F, found)
end
end
end
| _ => (CONS (key, data, bal, left, right), F, T)
in
if avl_t_is_empty avl then
(CONS (key, data, bal_zero, NIL, NIL), F)
else
let
prval _ = lemma_avl_t_param avl
val (avl, _, found) = $effmask_ntm search (avl, F, F)
in
(avl, found)
end
end
 
fn {key_t : t@ype} {data_t : t@ype}
avl_t_insert {size : int}
(avl : avl_t (key_t, data_t, size),
key : key_t,
data : data_t) :<>
[sz : pos] avl_t (key_t, data_t, sz) =
(avl_t_insert_or_replace<key_t><data_t> (avl, key, data)).0
 
fun {key_t : t@ype} {data_t : t@ype}
push_all_the_way_left (stack : List (avl_t (key_t, data_t)),
p : avl_t (key_t, data_t)) :
List0 (avl_t (key_t, data_t)) =
let
prval _ = lemma_list_param stack
in
case+ p of
| NIL => stack
| CONS (_, _, _, left, _) =>
push_all_the_way_left (p :: stack, left)
end
 
fun {key_t : t@ype} {data_t : t@ype}
update_generator_stack (stack : List (avl_t (key_t, data_t)),
right : avl_t (key_t, data_t)) :
List0 (avl_t (key_t, data_t)) =
let
prval _ = lemma_list_param stack
in
if avl_t_is_empty right then
stack
else
push_all_the_way_left<key_t><data_t> (stack, right)
end
 
fn {key_t : t@ype} {data_t : t@ype}
avl_t_make_data_generator {size : int}
(avl : avl_t (key_t, data_t, size)) :
() -<cloref1> Option data_t =
let
typedef avl_t = avl_t (key_t, data_t)
 
val stack = push_all_the_way_left<key_t><data_t> (LNIL, avl)
val stack_ref = ref stack
 
(* Cast stack_ref to its (otherwise untyped) pointer, so it can be
enclosed within ‘generate’. *)
val p_stack_ref = $UNSAFE.castvwtp0{ptr} stack_ref
 
fun
generate () :<cloref1> Option data_t =
let
(* Restore the type information for stack_ref. *)
val stack_ref =
$UNSAFE.castvwtp0{ref (List avl_t)} p_stack_ref
 
var stack : List0 avl_t = !stack_ref
var retval : Option data_t
in
begin
case+ stack of
| LNIL => retval := None ()
| p :: tail =>
let
val- CONS (_, d, _, left, right) = p
in
retval := Some d;
stack :=
update_generator_stack<key_t><data_t> (tail, right)
end
end;
!stack_ref := stack;
retval
end
in
generate
end
 
(*------------------------------------------------------------------*)
(* Hashmaps implemented with AVL trees and association lists. *)
 
(* The interface - - - - - - - - - - - - - - - - - - - - - - - - - *)
 
typedef hashmap_t (key_t : t@ype+,
data_t : t@ype+) =
avl_t (uint64, List1 @(key_t, data_t))
 
(* For simplicity, let us support only 64-bit hashes. *)
extern fun {key_t : t@ype} (* Implement a hash function with this. *)
hashmap_t$hashfunc : key_t -<> uint64
 
extern fun {key_t : t@ype} (* Implement key equality with this. *)
hashmap_t$key_eq : (key_t, key_t) -<> bool
 
extern fun
hashmap_t_nil :
{key_t : t@ype} {data_t : t@ype}
() -<> hashmap_t (key_t, data_t)
 
extern fun {key_t : t@ype}
{data_t : t@ype}
hashmap_t_set (map : hashmap_t (key_t, data_t),
key : key_t,
data : data_t) :<>
hashmap_t (key_t, data_t)
 
extern fun {key_t : t@ype}
{data_t : t@ype}
hashmap_t_get (map : hashmap_t (key_t, data_t),
key : key_t) :<>
Option data_t
 
(*
Notes:
* Generators for hashmap_t produce their output in unspecified
order.
* Generators for keys and data values can be made by analogy to
the following generator for pairs, or can be written in terms
of the generator for pairs. (The former approach seems better;
it might copy less data.)
*)
extern fun {key_t : t@ype}
{data_t : t@ype}
hashmap_t_make_pairs_generator (map : hashmap_t (key_t, data_t)) :
() -<cloref1> Option @(key_t, data_t)
 
(* The implementation - - - - - - - - - - - - - - - - - - - - - - - *)
 
implement
avl_t$compare<uint64> (u, v) =
if u < v then
~1
else if v < u then
1
else
0
 
implement
hashmap_t_nil () =
avl_t_nil ()
 
fun {key_t : t@ype}
{data_t : t@ype}
remove_association {n : nat} .<n>.
(lst : list (@(key_t, data_t), n),
key : key_t) :<>
List0 @(key_t, data_t) =
(* This implementation uses linear stack space, and so presumes the
list is not extremely long. It preserves the order of the list,
although doing so is not necessary for persistence. (You might
wish to think about that, taking into account that the
order of traversal through a hashmap usually is considered
"unspecified".) *)
case+ lst of
| list_nil () => lst
| list_cons (head, tail) =>
if hashmap_t$key_eq<key_t> (key, head.0) then
tail (* Assume there is only one match. *)
else
list_cons (head, remove_association (tail, key))
 
fun {key_t : t@ype}
{data_t : t@ype}
find_association {n : nat} .<n>.
(lst : list (@(key_t, data_t), n),
key : key_t) :<>
List0 @(key_t, data_t) =
(* This implementation is tail recursive. It will not build up the
stack. *)
case+ lst of
| list_nil () => lst
| list_cons (head, tail) =>
if hashmap_t$key_eq<key_t> (key, head.0) then
lst
else
find_association (tail, key)
 
implement {key_t} {data_t}
hashmap_t_set (map, key, data) =
let
typedef lst_t = List1 @(key_t, data_t) (* Association list. *)
val hash = hashmap_t$hashfunc<key_t> key
val lst_opt = avl_t_search_opt<uint64><lst_t> (map, hash)
val lst =
begin
case+ lst_opt of
| Some lst =>
(* There is already an association list for this hash value.
Remove any association already in it. *)
remove_association<key_t><data_t> (lst, key)
| None () =>
(* Start a new association list. *)
list_nil ()
end : List0 @(key_t, data_t)
val lst = list_cons (@(key, data), lst)
in
avl_t_insert<uint64><lst_t> (map, hash, lst)
end
 
implement {key_t} {data_t}
hashmap_t_get (map, key) =
let
typedef lst_t = List1 @(key_t, data_t) (* Association list. *)
val hash = hashmap_t$hashfunc<key_t> key
val lst_opt = avl_t_search_opt<uint64><lst_t> (map, hash)
in
case+ lst_opt of
| None () => None{data_t} ()
| Some lst =>
begin
case+ find_association<key_t><data_t> (lst, key) of
| list_nil () => None{data_t} ()
| list_cons (@(_, data), _) => Some{data_t} data
end
end
 
implement {key_t} {data_t}
hashmap_t_make_pairs_generator (map) =
let
typedef pair_t = @(key_t, data_t)
typedef lst_t = List1 pair_t
typedef lst_t_0 = List0 pair_t
 
val avl_gen = avl_t_make_data_generator<uint64><lst_t> (map)
 
val current_alist_ref : ref lst_t_0 = ref (list_nil ())
val current_alist_ptr =
$UNSAFE.castvwtp0{ptr} current_alist_ref
in
lam () =>
let
val current_alist_ref =
$UNSAFE.castvwtp0{ref lst_t_0} current_alist_ptr
in
case+ !current_alist_ref of
| list_nil () =>
begin
case+ avl_gen () of
| None () => None ()
| Some lst =>
begin
case+ lst of
| list_cons (head, tail) =>
begin
!current_alist_ref := tail;
Some head
end
end
end
| list_cons (head, tail) =>
begin
!current_alist_ref := tail;
Some head
end
end
end
 
(*------------------------------------------------------------------*)
 
implement
hashmap_t$hashfunc<string> (s) =
string_hash s
 
implement
hashmap_t$key_eq<string> (s, t) =
s = t
 
typedef s2i_hashmap_t = hashmap_t (string, int)
 
fn
s2i_hashmap_t_set (map : s2i_hashmap_t,
key : string,
data : int) :<> s2i_hashmap_t =
hashmap_t_set<string><int> (map, key, data)
 
fn
s2i_hashmap_t_set_ref (map : &s2i_hashmap_t >> _,
key : string,
data : int) :<!wrt> void =
(* Update a reference to a persistent hashmap. *)
map := s2i_hashmap_t_set (map, key, data)
 
fn
s2i_hashmap_t_get (map : s2i_hashmap_t,
key : string) :<> Option int =
hashmap_t_get<string><int> (map, key)
 
extern fun {} (* {} = a template without template parameters *)
s2i_hashmap_t_get_dflt$dflt :<> () -> int
fn {} (* {} = a template without template parameters *)
s2i_hashmap_t_get_dflt (map : s2i_hashmap_t,
key : string) : int =
case+ s2i_hashmap_t_get (map, key) of
| Some x => x
| None () => s2i_hashmap_t_get_dflt$dflt<> ()
 
overload [] with s2i_hashmap_t_set_ref
overload [] with s2i_hashmap_t_get_dflt
 
implement
main0 () =
let
implement s2i_hashmap_t_get_dflt$dflt<> () = 0
var map = hashmap_t_nil ()
var gen : () -<cloref1> @(string, int)
var pair : Option @(string, int)
in
map["one"] := 1;
map["two"] := 2;
map["three"] := 3;
println! ("map[\"one\"] = ", map["one"]);
println! ("map[\"two\"] = ", map["two"]);
println! ("map[\"three\"] = ", map["three"]);
println! ("map[\"four\"] = ", map["four"]);
gen := hashmap_t_make_pairs_generator<string><int> map;
for (pair := gen (); option_is_some pair; pair := gen ())
println! (pair)
end
 
(*------------------------------------------------------------------*)</syntaxhighlight>
 
{{out}}
<pre>$ patscc -O2 -DATS_MEMALLOC_GCBDW hashmaps-postiats.dats -lxxhash -lgc && ./a.out
map["one"] = 1
map["two"] = 2
map["three"] = 3
map["four"] = 0
Some((two, 2))
Some((one, 1))
Some((three, 3))</pre>
 
=={{header|AutoHotkey}}==
=== True arrays ===
[[AutoHotkey_L]] has [http://ahkscript.org/docs/Objects.htm Objects] which function as associative arrays.
<syntaxhighlight 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 !*+"]</syntaxhighlight>
=== Legacy versions ===
[[AutoHotkey_Basic]] does not have typical arrays.
However, variable names can be concatenated, simulating associative arrays.
<syntaxhighlight lang="autohotkey">arrayX1 = first
arrayX2 = second
arrayX3 = foo
arrayX4 = bar
Loop, 4
Msgbox % arrayX%A_Index%</syntaxhighlight>
 
=={{header|AutoIt}}==
See '''[https://msdn.microsoft.com/en-us/library/x4k5wbx4.aspx here]''' in the MSDN the reference for the Dictionary object that can be used in VBA. The following example shows how to create a dictionary, add/remove keys, change a key or a value, and check the existence of a key.
<syntaxhighlight lang="autoit">; Associative arrays in AutoIt.
; All the required functions are below the examples.
 
; Initialize an error handler to deal with any COM errors..
global $oMyError = ObjEvent("AutoIt.Error", "AAError")
 
; first example, simple.
global $simple
 
; Initialize your array ...
AAInit($simple)
 
AAAdd($simple, "Appple", "fruit")
AAAdd($simple, "Dog", "animal")
AAAdd($simple, "Silicon", "tetravalent metalloid semiconductor")
 
ConsoleWrite("It is well-known that Silicon is a " & AAGetItem($simple, "Silicon") & "." & @CRLF)
ConsoleWrite(@CRLF)
 
 
; A more interesting example..
 
$ini_path = "AA_Test.ini"
; Put this prefs section in your ini file..
; [test]
; foo=foo value
; foo2=foo2 value
; bar=bar value
; bar2=bar2 value
 
 
global $associative_array
AAInit($associative_array)
 
; We are going to convert this 2D array into a cute associative array where we
; can access the values by simply using their respective key names..
$test_array = IniReadSection($ini_path, "test")
 
for $z = 1 to 2 ; do it twice, to show that the items are *really* there!
for $i = 1 to $test_array[0][0]
$key_name = $test_array[$i][0]
ConsoleWrite("Adding '" & $key_name & "'.." & @CRLF)
; key already exists in "$associative_array", use the pre-determined value..
if AAExists($associative_array, $key_name) then
$this_value = AAGetItem($associative_array, $key_name)
ConsoleWrite("key_name ALREADY EXISTS! : =>" & $key_name & "<=" & @CRLF)
else
$this_value = $test_array[$i][1]
; store left=right value pair in AA
if $this_value then
AAAdd($associative_array, $key_name, $this_value)
endif
endif
next
next
 
ConsoleWrite(@CRLF & "Array Count: =>" & AACount($associative_array) & "<=" & @CRLF)
AAList($associative_array)
 
ConsoleWrite(@CRLF & "Removing 'foo'..")
AARemove($associative_array, "foo")
 
ConsoleWrite(@CRLF & "Array Count: =>" & AACount($associative_array) & "<=" & @CRLF)
AAList($associative_array)
 
 
AAWipe($associative_array)
 
 
; end
 
 
 
func AAInit(ByRef $dict_obj)
$dict_obj = ObjCreate("Scripting.Dictionary")
endfunc
 
; Adds a key and item pair to a Dictionary object..
func AAAdd(ByRef $dict_obj, $key, $val)
$dict_obj.Add($key, $val)
If @error Then return SetError(1, 1, -1)
endfunc
 
; Removes a key and item pair from a Dictionary object..
func AARemove(ByRef $dict_obj, $key)
$dict_obj.Remove($key)
If @error Then return SetError(1, 1, -1)
endfunc
 
; Returns true if a specified key exists in the associative array, false if not..
func AAExists(ByRef $dict_obj, $key)
return $dict_obj.Exists($key)
endfunc
 
; Returns a value for a specified key name in the associative array..
func AAGetItem(ByRef $dict_obj, $key)
return $dict_obj.Item($key)
endfunc
 
; Returns the total number of keys in the array..
func AACount(ByRef $dict_obj)
return $dict_obj.Count
endfunc
 
; List all the "Key" > "Item" pairs in the array..
func AAList(ByRef $dict_obj)
ConsoleWrite("AAList: =>" & @CRLF)
local $k = $dict_obj.Keys ; Get the keys
; local $a = $dict_obj.Items ; Get the items (for reference)
for $i = 0 to AACount($dict_obj) -1 ; Iterate the array
ConsoleWrite($k[$i] & " ==> " & AAGetItem($dict_obj, $k[$i]) & @CRLF)
next
endfunc
 
; Wipe the array, obviously.
func AAWipe(ByRef $dict_obj)
$dict_obj.RemoveAll()
endfunc
 
; Oh oh!
func AAError()
Local $err = $oMyError.number
If $err = 0 Then $err = -1
SetError($err) ; to check for after this function returns
endfunc
 
;; End AA Functions.
</syntaxhighlight>
 
=={{header|AWK}}==
Arrays in AWK are indeed associative arrays.
<syntaxhighlight 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
}</syntaxhighlight>
 
=={{header|Babel}}==
A simpler example which only creates the array and assigns a value.
 
<syntaxhighlight lang="babel">
'''Compiler:''' g++ 4.0.2
(("foo" 13)
("bar" 42)
("baz" 77)) ls2map !</syntaxhighlight>
 
=={{header|BASIC}}==
#include <map>
==={{header|BaCon}}===
<syntaxhighlight lang="qbasic">DECLARE associative ASSOC STRING
int
main( int argc, char* argv[] )
{
std::map< std::string, std::string > hash ;
hash[ "key-1" ] = "val1" ;
}
 
associative("abc") = "first three"
associative("xyz") = "last three"
 
PRINT associative("xyz")</syntaxhighlight>
==[[C sharp|C#]]==
[[Category:C sharp]]
'''Platform:''' [[.NET]] 1.x
 
{{out}}
System.Collections.HashTable map = new System.Collections.HashTable();
<pre>
map["key1"] = "foo";
prompt$ ./assoc
last three
</pre>
String keys, with ASSOC to a given data type. Sizing is dynamic.
 
==={{header|BASIC256}}===
<syntaxhighlight 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</syntaxhighlight>
{{out}}
<pre>a apple
b banana
c cucumber
 
I like to eat a cucumber on my salad.
a apple
e endive
c carrot</pre>
 
==={{header|BBC BASIC}}===
<syntaxhighlight 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%)</syntaxhighlight>
 
=={{header|Batch File}}==
This is cheating, I'm sure of it.
 
<syntaxhighlight 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
</syntaxhighlight>
 
{{out}}
<pre>array.dog = 1
array.cat = 2
array.wolf = 3
array.cow = 4
"sicko&flu" = 5
"sicko&measles" = 6
"sicko&mumps" = 7
"sicko&bromodrosis" = 8</pre>
 
=={{header|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.
<syntaxhighlight 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;</syntaxhighlight>
{{out}}
<pre>(fruit.melons bananas) (fruit.apples oranges kiwis)
formula.x^2+y^2</pre>
 
=={{header|Brat}}==
<syntaxhighlight 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</syntaxhighlight>
 
=={{header|C}}==
''Solution is at [[Associative arrays/Creation/C]]''.
 
=={{header|C sharp|C#}}==
'''Platform:''' [[.NET]] 1.x
<syntaxhighlight lang="csharp">System.Collections.HashTable map = new System.Collections.HashTable();
map["key1"] = "foo";</syntaxhighlight>
 
'''Platform:''' [[.NET]] 2.0
<syntaxhighlight lang="csharp">Dictionary<string, string> map = new Dictionary<string,string>();
map[ "key1" ] = "foo";</syntaxhighlight>
 
{{works with|C sharp|C#|3.0+}}
Dictionary<string, string> map = new Dictionary<string,string>();
<syntaxhighlight lang="csharp">var map = new Dictionary<string, string> {{"key1", "foo"}};</syntaxhighlight>
map[ "key1" ] = "foo";
 
==[[ColdFusion]]{{header|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'''.
[[Category:ColdFusion]]
 
<cfset myHash = structNew()>
<syntaxhighlight lang="cpp">#include <map></syntaxhighlight>
<cfset myHash.key1 = "foo">
 
<cfset myHash["key2"] = "bar">
===Creation===
<cfset myHash.put("key3","java-style")>
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:
<syntaxhighlight lang="cpp">std::map<A, B> exampleMap</syntaxhighlight>
 
If one wanted to us a key type of '''int''' and a value of '''double''', you would define it like so:
 
<syntaxhighlight lang="cpp">std::map<int, double> exampleMap</syntaxhighlight>
 
===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.
<syntaxhighlight lang="cpp">exampleMap[7] = 3.14</syntaxhighlight>
 
Of course, you can use a variable (or any [[rvalue]] of the correct type) for the key or value parameters:
<syntaxhighlight lang="cpp">int myKey = 7;
double myValue = 3.14;
exampleMap[myKey] = myValue;</syntaxhighlight>
====insert()====
The second approach is a little more complicated. We have to use the '''pair<>''' template:
<syntaxhighlight lang="cpp">exampleMap.insert(std::pair<int, double>(7,3.14));</syntaxhighlight>
or by using '''make_pair''' to avoid repeating key/value types:
<syntaxhighlight lang="cpp">exampleMap.insert(std::make_pair(7,3.14));</syntaxhighlight>
 
===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:
<syntaxhighlight lang="cpp">myValue = exampleMap[myKey]</syntaxhighlight>
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]]:
<syntaxhighlight 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;
}</syntaxhighlight>
 
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.
<syntaxhighlight 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;
}</syntaxhighlight>
 
=={{header|Ceylon}}==
<syntaxhighlight 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``");
}
}</syntaxhighlight>
 
=={{header|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.
 
<syntaxhighlight lang="text">// 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);</syntaxhighlight>
 
{{out}}
Keys: {foo, bar, baz}
Values: 1 4 6
Keys: {foo, baz}
Values: 1 6
arr2 keys: {John, Pete}
arr2 values: 3 14
 
=={{header|Clojure}}==
<syntaxhighlight lang="lisp">{:key "value"
:key2 "value2"
:key3 "value3"}</syntaxhighlight>
 
=={{header|ColdFusion}}==
<syntaxhighlight lang="cfm"><cfset myHash = structNew()>
<cfset myHash.key1 = "foo">
<cfset myHash["key2"] = "bar">
<cfset myHash.put("key3","java-style")></syntaxhighlight>
 
In ColdFusion, a map is literally a java.util.HashMap, thus the above 3rd method is possible.
 
==[[{{header|Common Lisp]]}}==
<syntaxhighlight lang="lisp">;; default :test is #'eql, which is suitable for numbers only,
[[Category:Common Lisp]
;; or for implementation identity for other types!
;; default :test is #'eql, which is suitable for numbers only,
;; Use #'equalp if you want case-insensitive keying on strings.
;; 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
==[[Java]]==
;; alist is written like this:
[[Category:Java]]
(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.</syntaxhighlight>
 
=={{header|Component Pascal}}==
===Defining a Map===
BlackBox Componente Builder<br/>
Using a handmade collections module with the following interface<br/>
<syntaxhighlight lang="oberon2">
DEFINITION Collections;
 
IMPORT Boxes;
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("foo", 5);
map.put("bar", 10);
map.put("baz", 15);
 
CONST
===Retreiving a value===
notFound = -1;
 
TYPE
map.get("foo") // => 5
Hash = POINTER TO RECORD
map.get("invalid") // => null
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
===Iterate over keys===
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
for (String key: map.keySet())
first-, last-: Node;
System.out.println(key);
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
===Iterate over values===
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;
for (int value: map.values())
PROCEDURE NewHashMap (cap: INTEGER): HashMap;
System.out.println(value);
PROCEDURE NewLinkedList (): LinkedList;
PROCEDURE NewVector (cap: INTEGER): Vector;
 
END Collections.
===Iterate over key,values===
</syntaxhighlight>
The program:
for (Map.Entry<String, Integer> entry: map.entrySet())
<syntaxhighlight lang="oberon2">
System.out.println(entry.getKey() + " => " + entry.getValue());
MODULE BbtAssociativeArrays;
IMPORT StdLog, Collections, Boxes;
 
PROCEDURE Do*;
==[[JavaScript]]==
VAR
[[Category:JavaScript]]
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.
In Javascript we make an associative array from an empty object, otherwise if we make it from an array we'll get all the Array object's method and properties when we iterate over it
</syntaxhighlight>
var assoc = {};
Execute:^Q BbtAssociativeArrays.Do<br/>
assoc['foo'] = 'bar';
{{out}}
assoc['another-key'] = 3;
<pre>
assoc.thirdKey = 'we can also do this!';
size: 4
for(key in assoc)
</pre>
 
=={{header|Crystal}}==
<syntaxhighlight lang="ruby">hash1 = {"foo" => "bar"}
 
# hash literals that don't perfectly match the intended hash type must be given an explicit type specification
# the following would fail without `of String => String|Int32`
hash2 : Hash(String, String|Int32) = {"foo" => "bar"} of String => String|Int32</syntaxhighlight>
 
=={{header|D}}==
<syntaxhighlight lang="d">void main() {
auto hash = ["foo":42, "bar":100];
assert("foo" in hash);
}</syntaxhighlight>
 
=={{header|Dao}}==
<syntaxhighlight 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</syntaxhighlight>
 
=={{header|Dart}}==
<syntaxhighlight lang="javascript">
main() {
var rosettaCode = { // Type is inferred to be Map<String, String>
'task': 'Associative Array Creation'
};
 
rosettaCode['language'] = 'Dart';
 
// The update function can be used to update a key using a callback
rosettaCode.update( 'is fun', // Key to update
(value) => "i don't know", // New value to use if key is present
ifAbsent: () => 'yes!' // Value to use if key is absent
);
assert( rosettaCode.toString() == '{task: Associative Array Creation, language: Dart, is fun: yes!}');
// If we type the Map with dynamic keys and values, it is like a JavaScript object
Map<dynamic, dynamic> jsObject = {
'key': 'value',
1: 2,
1.5: [ 'more', 'stuff' ],
#doStuff: () => print('doing stuff!') // #doStuff is a symbol, only one instance of this exists in the program. Would be :doStuff in Ruby
};
 
print( jsObject['key'] );
print( jsObject[1] );
for ( var value in jsObject[1.5] )
print('item: $value');
 
jsObject[ #doStuff ](); // Calling the function
print('\nKey types:');
jsObject.keys.forEach( (key) => print( key.runtimeType ) );
}
 
</syntaxhighlight>
{{out}}
<pre>
value
2
item: more
item: stuff
doing stuff!
 
Key types:
String
int
double
Symbol
</pre>
 
=={{header|Delphi}}==
<syntaxhighlight 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.</syntaxhighlight>
 
=={{header|Diego}}==
Diego has in-built <code>hash</code> and <code>dict</code> (short for 'dictionary') objects which function as associative arrays. The only exception is that <code>hash</code> can only accept uuid datatypes for keys. Diego also has <code>hash_</code> verb and <code>_hash</code> posit, used to hash an object/command.
 
To create a dictionary associative array:
<syntaxhighlight lang="diego">use_namespace(rosettacode)_me();
 
add_dict(tanzanianBanknoteObverseDipiction)_keys(500,1000,2000,5000,10000)_values(Karume,Nyerere,lion,black rhinoceros,elephant);
 
reset_ns[];</syntaxhighlight>
 
To create a hash associative array:
<syntaxhighlight lang="diego">use_namespace(rosettacode)_me();
 
add_hash(tanzanianBanknoteReverseDipiction)_values(
University of Dar es Salaam\, Central Hall Building,
Ikulu\, Dar es Salaam,
Ngome Kongwe\, Zanzibar,
Geita Cyanid Leaching Plant,
Bank of Tanzania Headquarters\, Dar es Salaam
);
 
reset_ns[];</syntaxhighlight>
 
=={{header|Dyalect}}==
 
Dyalect has a <code>Tuple</code> data type which allows to add labels to values:
 
<syntaxhighlight lang="dyalect">var t = (x: 1, y: 2, z: 3)
print(t.Keys().ToArray())</syntaxhighlight>
 
{{out}}
 
<pre>[x, y, z]</pre>
 
=={{header|E}}==
<syntaxhighlight 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)</syntaxhighlight>
=={{header|EasyLang}}==
<syntaxhighlight>
# use array of array for this
proc hashGet ind$ . ar$[][] item$ .
for i to len ar$[][]
if ar$[i][1] = ind$
item$ = ar$[i][2]
return
.
.
item$ = ""
.
proc hashSet ind$ val$ . ar$[][] .
for i to len ar$[][]
if ar$[i][1] = ind$
ar$[i][2] = val$
return
.
.
.
clothing$[][] = [ [ "type" "t-shirt" ] [ "color" "red" ] ]
clothing$[][] &= [ "size" "xl" ]
#
hashSet "color" "green" clothing$[][]
hashGet "color" clothing$[][] col$
print col$
</syntaxhighlight>
 
=={{header|EchoLisp}}==
<syntaxhighlight 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
</syntaxhighlight>
 
=={{header|Ecstasy}}==
Defining the Map:
<syntaxhighlight lang="java">Map<String, Int> map = new HashMap();
map["foo"] = 5; // or: map.put("foo", 5)
map["bar"] = 10;
map["baz"] = 15;
map["foo"] = 6; // replaces previous value of 5</syntaxhighlight>
Literal map notation:
<syntaxhighlight lang="java">Map<String, Int> map = ["foo"=6, "bar"=10, "baz"=15];</syntaxhighlight>
Retrieving a value:
<syntaxhighlight lang="java">Int? mightBeNull = map["foo"];
Int neverNull = map.getOrDefault("foo", 0);
if (Int n := map.get("foo")) {
// if "foo" is in the map, then the variable "n" is set to its value
} else {
// if "foo" is not in the map, then the variable "n" is not defined
}</syntaxhighlight>
Iterate over keys:
<syntaxhighlight lang="java">for (String key : map) {
// the variable "key" is defined here
}</syntaxhighlight>
Iterate over values:
<syntaxhighlight lang="java">for (Int value : map.values) {
// the variable "value" is defined here
}</syntaxhighlight>
Iterate over key, value pairs:
<syntaxhighlight lang="java">for ((String key, Int value) : map) {
// the variables "key" and "value" are defined here
}</syntaxhighlight>
 
=={{header|Elena}}==
ELENA 5.0:
<syntaxhighlight lang="elena">import system'collections;
public program()
{
// 1. Create
var map := Dictionary.new();
map["key"] := "foox";
map["key"] := "foo";
map["key2"]:= "foo2";
map["key3"]:= "foo3";
map["key4"]:= "foo4";
}</syntaxhighlight>
 
=== Strong typed dictionary ===
<syntaxhighlight lang="elena">import system'collections;
 
public program()
{
// 1. Create
auto map := new Map<string,string>();
map["key"] := "foox";
map["key"] := "foo";
map["key2"]:= "foo2";
map["key3"]:= "foo3";
map["key4"]:= "foo4";
}</syntaxhighlight>
 
=={{header|Elixir}}==
===Map literals===
An empty map:
 
<syntaxhighlight lang="elixir">
%{}
</syntaxhighlight>
 
A map with key-value pairs of different types:
 
<syntaxhighlight lang="elixir">
%{"one" => :two, 3 => "four"}
</syntaxhighlight>
 
Maps with atoms as keys:
 
<syntaxhighlight lang="elixir">
%{a: 1, b: 2}
# equivalent to
%{:a => 1, :b => 2}
</syntaxhighlight>
 
===Programmatic map creation===
{{trans|Erlang}}
<syntaxhighlight 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</syntaxhighlight>
 
{{out}}
<pre>
< create Map.new >
%{bar: 2, foo: 1}
:bar => 2
:foo => 1
%{bar: 2, foo: 3}
:bar => 2
:foo => 3
</pre>
 
=={{header|Emacs Lisp}}==
<syntaxhighlight lang="lisp">(setq my-table (make-hash-table))
(puthash 'key 'value my-table)</syntaxhighlight>
 
<code>make-hash-table</code> compares keys with <code>eql</code> by default. This suits symbols and numbers (including floating point). For string keys an <code>equal</code> test can be used,
 
<syntaxhighlight lang="lisp">(setq my-table (make-hash-table :test 'equal))
(puthash "key" 123 my-table)</syntaxhighlight>
 
<code>define-hash-table-test</code> can create other key comparison types.
 
=={{header|EMal}}==
<syntaxhighlight lang="emal">
Map empty = Map(int, text) # creates an empty map
writeLine(empty)
var longFruit = Map(int, text).of(1, "banana") # creates a map with the pair 1 => "banana"
longFruit[2] = "melon" # associates a key of 2 with "melon"
longFruit.insert(3, "avocado")
writeLine(longFruit) # prints the map
var shortFruit = int%text[4 => "kiwi", 5 => "apple"] # map creation using arrow notation
writeLine(shortFruit[5]) # retrieves the value with a key of 5 and prints it out
writeLine(shortFruit.length) # prints the number of entries
writeLine(shortFruit) # prints the map
writeLine(text%text["Italy" => "Rome", "France" => "Paris", "Germany" => "Berlin", "Spain" => "Madrid"])
 
</syntaxhighlight>
{{out}}
<pre>
[]
[1:banana,2:melon,3:avocado]
apple
2
[4:kiwi,5:apple]
[Italy:Rome,France:Paris,Germany:Berlin,Spain:Madrid]
</pre>
 
=={{header|Erlang}}==
Erlang offers several associative array type data structures, this example uses the dictionary data structure.
<syntaxhighlight 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)).
</syntaxhighlight>
 
{{out}}
32> assoc:test_create().
bar: 2
foo: 1
bar: 2
foo: 3
ok
 
=={{header|F Sharp|F#}}==
.NET 3.5 Generic Dictionary (mutable)
<syntaxhighlight lang="fsharp">
let dic = System.Collections.Generic.Dictionary<string,string>() ;;
dic.Add("key","val") ;
dic.["key"] <- "new val" ;
</syntaxhighlight>
Functional dictionary (immutable)
<syntaxhighlight 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"
</syntaxhighlight>
 
=={{header|Factor}}==
Associative mappings follow the associative protocol. See [http://docs.factorcode.org/content/article-assocs-protocol.html the docs].
Here's an example using a hashtable that can be run in the listener :
<syntaxhighlight 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</syntaxhighlight>
 
=={{header|Fantom}}==
 
Associative arrays are called 'maps' in Fantom:
 
<syntaxhighlight lang="fantom">
class Main
{
public static Void main ()
{
// create a map which maps Ints to Strs, with given key-value pairs
alert('key:"'+key+'", value:"'+assoc[key]+'"');
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
}
 
}
}
</syntaxhighlight>
 
=={{header|Forth}}==
The above associative array can also be constructed using Javascript's object literal syntax
{{works with|GNU Forth|0.6.2}}
 
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.
var assoc = {
foo:'bar',
'another-key':3, //the key can either be enclosed by quotes or not
thirdKey = 'we can also do this!'
};
 
<syntaxhighlight lang="forth">: get ( key len table -- data ) \ 0 if not present
==[[Lua]]==
search-wordlist if
[[Category:Lua]]
>body @
else 0 then ;
 
: put ( data key len table -- )
Lua tables are Hashes
>r 2dup r@ search-wordlist if
hash = {}
r> drop nip nip
hash[ "key-1" ] = "val1"
>body !
hash[ "key-2" ] = 1
else
hash[ "key-3" ] = {}
r> get-current >r set-current \ switch definition word lists
Returns nil on unknown key.
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</syntaxhighlight>
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 <tt>table</tt> and <tt>table-find</tt>, replacing <tt>wordlist</tt> and <tt>search-wordlist</tt>, respectively.
 
(The use of <tt>nextname ( str len -- )</tt> is a GNU Forth extension to <tt>create</tt>; there is no means in the ANS standard to use a string on the stack to create a dictionary entry.)
 
{{libheader|Forth Foundation Library}}
 
Hashtable for mapping strings to integer
<syntaxhighlight 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
==[[Objective C]]==
[[Category:Objective C]]
 
s" bar" htable hct-get [IF]
In Objective C, you will use the NSMutableDictionary class to create a hash. To map to an integer, you will also need to make use of the NSNumber class.
.( Value:) . cr
[ELSE]
.( Entry not present.) cr
[THEN]</syntaxhighlight>
{{works with|4tH|3.64}}
 
Similar functionality is available in 4tH. A binary search is applied to search values, hence hashtables can be quite compact.
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
<syntaxhighlight lang="text">include lib/hash.4th
include lib/hashkey.4th
\ Create a hash table 'table' with a starting size of 10
[dict setObject:[NSNumber numberWithInt:2] forKey:@"Two"];
[dict setObject:[NSNumber numberWithInt:7] forKey:@"Seven"];
int two = [dict objectForKey:@"Two"];
int seven = [dict objectForKey:@"Seven"];
 
['] fnv1a is hash \ set hash method
==[[OCaml]]==
10 constant /htable \ determine the size
[[Category:OCaml]]
/htable array htable \ allocate the table
A simple idiom to create a hash table mapping strings to integers:
latest /htable hashtable \ turn it into a hashtable
\ Insert entries
5 s" foo" htable put
10 s" bar" htable put
15 s" baz" htable put
\ Get entry from the table
s" bar" htable get error? if
.( Entry not present.) cr drop
else
.( Value: ) . cr
then
</syntaxhighlight>
 
=={{header|FreeBASIC}}==
let hash = Hashtbl.create 0;;
Uses unions to store the keys and associated values, and FreeBASIC's ability to resize arrays makes adding new entries easy.
List.iter (fun (key, value) -> Hashtbl.add hash key value)
<syntaxhighlight lang="freebasic">#define max(a, b) Iif(a>b,a,b)
["foo", 5; "bar", 10; "baz", 15];;
 
enum datatype
To retrieve a value:
'for this demonstration we'll allow these five data types
BOOL
STRNG
BYYTE
INTEG
FLOAT
end enum
 
union value
let bar = Hashtbl.find hash "bar";; (* bar = 5 *)
bool as boolean
strng as string*32
byyte as byte
integ as integer
float as double
end union
 
type dicitem
To retrieve a value, returning a default if the key is not found:
'one part of the dictionary entry, either the key or the value
datatype as datatype 'need to keep track of what kind of data it is
value as value
end type
 
type dicentry
'a dic entry has two things, a key and a value
key as dicitem
value as dicitem
end type
 
sub add_dicentry( Dic() as dicentry, entry as dicentry )
redim preserve Dic(0 to max(ubound(Dic)+1,0))
Dic(ubound(Dic)) = entry
return
end sub
 
redim as dicentry Dictionary(-1) 'initialise a dictionary with no entries as yet
 
dim as dicentry thing1, thing2
 
'generate some test dictionary entries
with thing1
with .key
.datatype = STRNG
.value.strng = "Cat"
end with
with .value
.datatype = STRNG
.value.strng = "Mittens"
end with
end with
 
with thing2
let quux = try Hashtbl.find hash "quux" with Not_found -> some_value;;
with .key
.datatype = integ
.value.integ = 32767
end with
with .value
.datatype = float
.value.float = 2.718281828
end with
end with
 
add_dicentry( Dictionary(), thing1 )
==[[Perl]]==
add_dicentry( Dictionary(), thing2 )
[[Category:Perl]]
'''Interpeter:''' Perl
 
print Dictionary(0).value.value.strng
Defining a Hash
print Dictionary(1).key.value.integ</syntaxhighlight>
{{out}}
<pre>
Mittens
32767
</pre>
 
=={{header|Free Pascal}}==
# using => key does not need to be quoted unless it contains special chars
FPC 3.2.0.+. Similar to Delphi.
my %hash = (
<syntaxhighlight lang="pascal">program AssociativeArrayCreation;
key1 => 'val1',
{$IFDEF FPC}{$MODE DELPHI}{$ENDIF}
'key-2' => 2,
{$IFDEF WINDOWS}{$APPTYPE CONSOLE}{$ENDIF}
three => -238.83,
uses Generics.Collections;
4 => 'val3',
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.</syntaxhighlight>
FPC 2.4+. Using FGL instead of rtl-generics:
<syntaxhighlight lang="pascal">program AssociativeArrayCreation;
{$IFDEF WINDOWS}{$APPTYPE CONSOLE}{$ENDIF}
{$MODE DELPHI}
uses fgl;
var
# using , both key and value need to be quoted if containing something non-numeric in nature
lDictionary: TFPGMap<string, Integer>;
my %hash = (
begin
'key1', 'val1',
lDictionary := TFPGMap<string, Integer>.Create;
'key-2', 2,
try
'three', -238.83,
4, lDictionary.Add('val3foo', 5);
lDictionary.Add('bar', 10);
);
lDictionary.Add('baz', 15);
finally
lDictionary.Free;
end;
end.</syntaxhighlight>
 
=={{header|Futhark}}==
Defining a HashRef
<syntaxhighlight lang="futhark">let associative_array = {key1=1,key2=2}</syntaxhighlight>
 
my $hashref = {
key1 => 'val1',
'key-2' => 2,
three => -238.83,
4 => 'val3',
}
 
=={{header|FutureBasic}}==
Using a Hash
<syntaxhighlight lang="futurebasic">
void local fn DoIt
CFDictionaryRef dict1 = fn DictionaryWithObjects( @"Alpha", @"A", @"Bravo", @"B", @"Charlie", @"C", @"Delta", @"D", NULL )
CFDictionaryRef dict2 = @{@"A":@"Alpha", @"B":@"Bravo", @"C":@"Charlie", @"D":@"Delta"}
CFMutableDictionaryRef dict3 = fn MutableDictionaryWithCapacity(0)
MutableDictionarySetObjectForKey( dict3, @"Alpha", @"A" )
MutableDictionarySetObjectForKey( dict3, @"Bravo", @"B" )
MutableDictionarySetObjectForKey( dict3, @"Charlie", @"C" )
MutableDictionarySetObjectForKey( dict3, @"Delta", @"D" )
CFMutableDictionaryRef dict4 = fn MutableDictionaryWithDictionary( @{@"A":@"Alpha", @"B":@"Bravo", @"C":@"Charlie", @"D":@"Delta"} )
print fn DictionaryObjectForKey( dict1, @"A" )
print dict1[@"B"]
print dict2[@"C"]
print dict3[@"D"]
print dict4
end fn
 
fn DoIt
print $hash{'key1'};
 
HandleEvents
</syntaxhighlight>
 
{{out}}
<pre>
Alpha
Bravo
Charlie
Delta
{
A = Alpha;
B = Bravo;
C = Charlie;
D = Delta;
}
</pre>
 
=={{header|Gambas}}==
See [[http://rosettacode.org/wiki/Associative_array/Iteration#Gambas Associative array/Iteration]]
 
=={{header|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.
<syntaxhighlight 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,
}</syntaxhighlight>
 
=={{header|Gosu}}==
As an OOP language with generics Gosu can use any variety of Map classes. In addition Gosu provides associative array syntax for all objects.
<syntaxhighlight lang="javascript">// empty map
var emptyMap = new HashMap<String, Integer>()
 
// map initialization
var map = {"Scott"->50, "Carson"->40, "Luca"->30, "Kyle"->38}
 
// map key/value assignment
map["Scott"] = 51
 
// get a value
var x = map["Scott"]
// remove an entry
$hash{'key1'} = 'val1';
map.remove("Scott")
// loop and maps
@hash{'key1', 'three'} = ('val1', -238.83);
for(entry in map.entrySet()) {
print("Key: ${entry.Key}, Value: ${entry.Value}")
}
 
// functional iteration
Using a HashRef
map.eachKey(\ k ->print(map[k]))
map.eachValue(\ v ->print(v))
map.eachKeyAndValue(\ k, v -> print("Key: ${v}, Value: ${v}"))
var filtered = map.filterByValues(\ v ->v < 50)
 
// any object can be treated as an associative array
print $hash->{'key1'};
class Person {
var name: String
var age: int
}
// access properties on Person dynamically via associative array syntax
var scott = new Person()
scott["name"] = "Scott"
scott["age"] = 29</syntaxhighlight>
 
=={{header|Groovy}}==
Create an empty map and add values
<syntaxhighlight 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')</syntaxhighlight>
 
Create a pre-populated map and verify values
<syntaxhighlight 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')</syntaxhighlight>
 
=={{header|Harbour}}==
Create an empty array and add values:
<syntaxhighlight lang="visualfoxpro">arr := { => }
arr[ 10 ] := "Val_10"
arr[ "foo" ] := "foovalue"</syntaxhighlight>
Create and initialize array:
<syntaxhighlight lang="visualfoxpro">arr := hb_Hash( 10, "Val_10", "foo", "foovalue" )
// or
arr := { 10 => "Val_10", "foo" => "foovalue" }</syntaxhighlight>
 
=={{header|Haskell}}==
Binary trees:
{{works with|GHC}}
<syntaxhighlight lang="haskell">import Data.Map
 
dict = fromList [("key1","val1"), ("key2","val2")]
 
ans = Data.Map.lookup "key2" dict -- evaluates to Just "val2"
</syntaxhighlight>
 
It is also possible to use association lists (lists of pairs). It is inefficient (O(n) lookup), but simple.
<syntaxhighlight lang="haskell">dict = [("key1","val1"), ("key2","val2")]
 
ans = lookup "key2" dict -- evaluates to Just "val2"
</syntaxhighlight>
 
GHC also had an imperative hash table implementation in the <code>Data.HashTable</code> module, but was removed in <code>GHC 7.8</code>.
 
Other standard associatives arrays libraries are : <code>Data.IntMap</code> and <code>Data.HasMap</code>
 
=={{header|hexiscript}}==
<syntaxhighlight lang="hexiscript">let d dict 2 # Initial estimated size
let d["test"] "test" # Strings can be used as index
let d[123] 123 # Integers can also be used as index
 
println d["test"]
println d[123]</syntaxhighlight>
 
=={{header|Icon}} and {{header|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.
 
<syntaxhighlight lang="icon">procedure main()
local t
t := table()
t["foo"] := "bar"
write(t["foo"])
end</syntaxhighlight>
 
=={{header|Inform 7}}==
The Inform 7 equivalent of an associative array is a relation between values.
 
===Static relation===
<syntaxhighlight 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.</syntaxhighlight>
 
===Dynamic relation===
<syntaxhighlight 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.</syntaxhighlight>
 
=={{header|Insitux}}==
 
It is possible to use any value type for both keys and values for a dictionary in Insitux.
 
<syntaxhighlight lang="insitux">{
:a "value" ;keyword key, string value
:b 123 ;keyword key, number value
456 [1 2 3] ;number key, vector value
[5 6 7] :b ;vector key, keyword value
{:a 1} {:b 2} ;dictionary key, dictionary value
}</syntaxhighlight>
 
<syntaxhighlight lang="insitux">;use dictionary as function for lookup; commas for readability, treated as white-space
> ({:a 1, :b 2, :c 3} :b)
2</syntaxhighlight>
 
<syntaxhighlight lang="insitux">;extend existing dictionary by using it as a function with two arguments
> ({:a 1, :b 2, :c 3} :b 3)
{:a 1, :b 3, :c 3}</syntaxhighlight>
 
=={{header|Ioke}}==
<syntaxhighlight lang="ioke">{a: "a", b: "b"}</syntaxhighlight>
 
=={{header|J}}==
 
Usually, in J, you would use a named pair of (same length) lists for this purpose - one of keys, one of values. There are a number of details here that vary with the the intended use patterns. (First you get it working and then if you run into bottlenecks you rebuild things to relieve the problems).
 
However, it's also possible to use the symbol table itself to hold the names. The symbol table has limitations (can only accept syntactically valid names), but we can turn arbitrary strings into valid symbols using base 62 encode and prefixing with a letter (hypothetically speaking, base 64 encode would let us build longer names than base 62, because of computational complexity issues - but the J symbol table also comes with a name length limit - 255 characters - and does not support 64 different characters in names):
 
<syntaxhighlight 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'</syntaxhighlight>
 
Example use:
 
<syntaxhighlight 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''</syntaxhighlight>
 
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).
 
=={{header|Jakt}}==
<syntaxhighlight lang="jakt">
fn main() {
let dictionary = ["foo": 1, "bar": 2]
println("{}", dictionary)
}
</syntaxhighlight>
 
=={{header|Java}}==
<p>
Java offers an associative array, referred to as a <code>Map</code>, as part of the Collections Framework.<br />
There are numerous implementing classes, each which provide unique functionality for various tasks.<br />
</p>
<p>
It's worth noting that Java also offers the <code>Dictionary</code> class, which appears to be less preferred, according to Java.<br />
<kbd><i>"[The Map] interface takes the place of the Dictionary class ..."</i></kbd>.
</p>
<p>
The most generalized <code>Map</code> would be the <code>HashMap</code>, which is a basic, unordered, set of <kbd>keys</kbd> and <kbd>values</kbd>.<br />
There is also the <code>LinkedHashMap</code>, which will preserve the order of input.<br />
There is the <code>TreeMap</code>, which is used to store the <kbd>key</kbd>s in a specific order, using the <kbd>key</kbd>'s <code>compareTo</code> method.
Optionally, you could provide your own <kbd>comparator</kbd> using the <code>Comparator</code> interface, which I'll demonstrate below.<br />
There are numerous other implementing classes, which can be found under the <code>Map</code> <kbd>Javadoc</kbd>,
[https://docs.oracle.com/en/java/javase/20/docs/api/java.base/java/util/Map.html. Map (Java SE 20 & JDK 20)].
</p>
<p>
Here is a basic implementation of a <code>HashMap</code>.
</p>
<syntaxhighlight lang="java">
Map<String, Integer> map = new HashMap<>();
</syntaxhighlight>
<p>
To add a <kbd>key</kbd> and <kbd>value</kbd> pair, you use the <code>Map.put</code> method.<br />
A useful feature of <code>Map.put</code> is that if the <kbd>key</kbd> already exists, thus is being overridden,
it will return the overridden value, otherwise <code>null</code>.
</p>
<syntaxhighlight lang="java">
map.put("rosetta", 100);
map.put("code", 200);
</syntaxhighlight>
<p>
To get a <kbd>value</kbd>, you use the <code>Map.get</code> method, specifying the <kbd>key</kbd> as the parameter.<br />
If the specified <kbd>key</kbd> does not exist, <code>null</code> is returned.
</p>
<syntaxhighlight lang="java">
int valueA = map.get("rosetta");
int valueB = map.get("code");
</syntaxhighlight>
<p>
To mutate a <kbd>key</kbd>'s <kbd>value</kbd>, you use the <code>Map.replace</code> method.
</p>
<syntaxhighlight lang="java">
map.replace("rosetta", 300);
</syntaxhighlight>
<p>
Alternately, you can replace the <kbd>value</kbd>, only if it is of a current <kbd>value</kbd>.<br />
So, in this example it will return <kbd>true</kbd>, only if the <kbd>key</kbd> <kbd><i>"rosetta"</i></kbd> had the current <kbd>value</kbd> of <kbd><i>100</i></kbd>.
</p>
<syntaxhighlight lang="java">
boolean replaced = map.replace("rosetta", 100, 300);
</syntaxhighlight>
<p>
To check for the existence of a <kbd>key</kbd>, you use the <code>containsKey</code> method.
</p>
<syntaxhighlight lang="java">
boolean contains = map.containsKey("rosetta");
</syntaxhighlight>
<p>
And to check for the existence of a <kbd>value</kbd>, you use the <code>containsValue</code> method.
</p>
<syntaxhighlight lang="java">
boolean contains = map.containsValue(100);
</syntaxhighlight>
<p>
A <code>LinkedHashMap</code> is exactly the same as a <code>HashMap</code>, except it will preserve the order in which the <kbd>key</kbd>s were added.
</p>
<syntaxhighlight lang="java">
Map<String, Integer> map = new LinkedHashMap<>();
map.put("rosetta", 100);
map.put("code", 200);
</syntaxhighlight>
<p>
A <code>TreeMap</code> is useful for when you want the <kbd>key</kbd>s in a specific order.<br />
By default, it will use the <kbd>key</kbd>'s <code>compareTo</code> method, to determine the order.<br />
So, if you're <kbd>key</kbd> is a <code>String</code>, the order will be ascending, similar to an actual dictionary.
</p>
<syntaxhighlight lang="java">
Map<String, Integer> map = new TreeMap<>();
map.put("rosetta", 100);
map.put("code", 200);
</syntaxhighlight>
<p>
You could, optionally, specify a comparator by implementing a <code>Comparator</code> interface.<br />
A <code>TreeMap</code>, conveniently, only requires you to implement the <code>compare</code> method of the <code>Comparator</code>,
so the implementation can be done as an <kbd>anonymous class</kbd>.
</p>
<syntaxhighlight lang="java">
Comparator<String> comparator = new Comparator<String>() {
public int compare(String stringA, String stringB) {
if (stringA.compareTo(stringB) > 0) {
return -1;
} else if (stringA.compareTo(stringB) < 0) {
return 1;
}
return 0;
}
};
</syntaxhighlight>
<p>
Which you then supply as an argument to the constructor.
</p>
<syntaxhighlight lang="java">
Map<String, Integer> map = new TreeMap<>(comparator);
</syntaxhighlight>
<p>
To make things even simpler, you could use a <kbd>lambda</kbd> for the <kbd>anonymous class</kbd>.
</p>
<syntaxhighlight lang="java">
Comparator<String> comparator = (stringA, stringB) -> {
if (stringA.compareTo(stringB) > 0) {
return -1;
} else if (stringA.compareTo(stringB) < 0) {
return 1;
}
return 0;
};
</syntaxhighlight>
 
=={{header|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.
<syntaxhighlight 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] + '"');
}
}</syntaxhighlight>
 
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.
<syntaxhighlight 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));
}</syntaxhighlight>
 
=={{header|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".
<syntaxhighlight 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"</syntaxhighlight>
 
===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.
<syntaxhighlight 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] ] );</syntaxhighlight>
'''Example''':
<syntaxhighlight lang="jq">{} | addKey(1;"one") | addKey(2; "two") | removeKey(1) | getKey(2)</syntaxhighlight>
produces:
<syntaxhighlight lang="sh">"two"</syntaxhighlight>
 
=={{header|Jsish}}==
From Javascript. jsish warns of duplicate ''var'', in this case the ''assoc'' variable is reused.
<syntaxhighlight lang="javascript">var assoc = {};
$hash->{assoc['key1foo'}] = 'val1bar';
assoc['another-key'] = 3;
// dot notation can be used if the property name is a valid identifier
@hash->{'key1', 'three'} = ('val1', -238.83);
assoc.thirdKey = 'we can also do this!';
assoc[2] = "the index here is the string '2'";
;assoc;
//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)) {
puts('key:"' + key + '", value:"' + assoc[key] + '"');
}
}
;assoc;
 
/*
=!EXPECTSTART!=
associativeArray.jsi:12: warn: duplicate var: assoc
assoc ==> { 2:"the index here is the string \'2\'", "another-key":3, foo:"bar", thirdKey:"we can also do this!" }
key:"another-key", value:"3"
key:"foo", value:"bar"
assoc ==> { "another-key":3, foo:"bar" }
=!EXPECTEND!=
*/</syntaxhighlight>
{{out}}
<pre>prompt$ jsish -u associativeArray.jsi
[PASS] associativeArray.jsi</pre>
 
=={{header|Julia}}==
{{works with|Julia|0.6}}
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.
<syntaxhighlight lang="julia">dict = Dict('a' => 97, 'b' => 98) # list keys/values
# Dict{Char,Int64} with 2 entries:
# 'b' => 98
# 'a' => 97
 
dict = Dict(c => Int(c) for c = 'a':'d') # dict comprehension
# Dict{Char,Int64} with 4 entries:
# 'b' => 98
# 'a' => 97
# 'd' => 100
# 'c' => 99
 
dict['é'] = 233; dict # add an element
# Dict{Char,Int64} with 3 entries:
# 'b' => 98
# 'a' => 97
# 'é' => 233
 
emptydict = Dict() # create an empty dict
# Dict{Any,Any} with 0 entries
 
dict["a"] = 1 # type mismatch
# ERROR: MethodError: Cannot `convert` an object of type String to an object of type Char
 
typeof(dict) # type is infered correctly
# Dict{Char,Int64}
</syntaxhighlight>
 
=={{header|K}}==
Keys in a dictionary must be symbols (`symbol).
<syntaxhighlight lang="k"> / creating an dictionary
d1:.((`foo;1); (`bar;2); (`baz;3))
 
/ extracting a value
d1[`bar]
2</syntaxhighlight>
Another approach.
<syntaxhighlight lang="k"> d2: .() / create empty dictionary
d2[`"zero"]:0
d2[`"one"]:1
d2[`"two"]:2
 
d2
.((`zero;0;)
(`one;1;)
(`two;2;))</syntaxhighlight>
 
Extracting the keys and values.
<syntaxhighlight lang="k"> !d2 / the keys
`zero `one `two
 
d2[] / the values
0 1 2</syntaxhighlight>
 
=={{header|Kotlin}}==
{{trans|Java}}
<syntaxhighlight 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("foo" in map) // => true
println("invalid" in map) // => 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")
}</syntaxhighlight>
 
=={{header|Lambdatalk}}==
Associative arrays are not currently built in the JS.js kernel of lambdatalk but are added via the lib_hash library page.
<syntaxhighlight lang="scheme">
 
1) a (currently) reduced set of functions:
 
HASH: [5] [H.lib, H.new, H.disp, H.get, H.set!]
 
2) building an associative array: {def H key value | ...}
 
{def capitals
{H.new nyk New York, United States |
lon London, United Kingdom |
par Paris, France |
mos Moscou, Russia }}
-> capitals
 
3) displaying: {H.disp hash}
{H.disp {capitals}}
->
[
nyk: New York, United States
lon: London, United Kingdom
par: Paris, France
mos: Moscou, Russia
]
 
4) getting a value from a key: {H.get hash key}
 
{H.get {capitals} nyk} -> New York, United States
{H.get {capitals} lon} -> London, United Kingdom
{H.get {capitals} par} -> Paris, France
{H.get {capitals} mos} -> Moscou, Russia
 
5) adding a new (key,value): {H.set! hash key value}
 
{H.disp {H.set! {capitals} bar Barcelona, Catalunya}}
->
[
nyk: New York, United States
lon: London, United Kingdom
par: Paris, France
mos: Moscou, Russia
bar: Barcelona, Catalunya
]
 
6) editing a key
 
{H.disp
{H.set! {capitals}
nyk
{H.get {capitals} nyk} of America}} // adding "of America" to nyk
->
[
nyk: New York, United States of America
lon: London, United Kingdom
par: Paris, France
mos: Moscou, Russia
bar: Barcelona, Catalunya
]
</syntaxhighlight>
 
=={{header|Lang5}}==
<syntaxhighlight 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 .</syntaxhighlight>
 
=={{header|langur}}==
Hash keys in langur may be numbers or strings. Number keys are simplified, so that 1.0 is the same key as 1.
 
<syntaxhighlight lang="langur">var .hash = {1: "abc", "1": 789}
 
# may assign with existing or non-existing hash key (if hash is mutable)
.hash[7] = 49
 
writeln .hash[1]
writeln .hash[7]
writeln .hash["1"]
 
# using an alternate value in case of invalid index; prevents exception
writeln .hash[1; 42]
writeln .hash[2; 42]</syntaxhighlight>
 
{{out}}
<pre>abc
49
789
abc
42</pre>
 
=={{header|Lasso}}==
<syntaxhighlight 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
'<br />'
#mymap -> find(3) // Wednesday, found by the key not the position
'<br />'
 
// Get all keys from a map
#mymap -> keys // staticarray(2, fourth, one, 3)
'<br />'
 
// Iterate thru a map and get values
with v in #mymap do {^
#v
'<br />'
^}
// Tuesday<br />Thursday<br />Monday<br />Wednesday<br />
 
// Perform actions on each value of a map
#mymap -> foreach => {
#1 -> uppercase
#1 -> reverse
}
#mymap // map(2 = YADSEUT, fourth = YADSRUHT, one = YADNOM, 3 = YADSENDEW)</syntaxhighlight>
 
=={{header|LFE}}==
<syntaxhighlight 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))))
 
</syntaxhighlight>
 
=={{header|Liberty BASIC}}==
Needs the sublist library from http://basic.wikispaces.com/SubList+Library since LB does not have built-in associative arrays.
<syntaxhighlight 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")
</syntaxhighlight>
Key 'green' is associated with data item 50 255 50
 
=={{header|Lingo}}==
<syntaxhighlight lang="lingo">props = [#key1: "value1", #key2: "value2"]
 
put props[#key2]
-- "value2"
put props["key2"]
-- "value2"
put props.key2
-- "value2"
put props.getProp(#key2)
-- "value2"</syntaxhighlight>
 
=={{header|LiveCode}}==
Livecode arrays are only associative, but can be accessed by ordinal if they are used as the key.
<syntaxhighlight 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</syntaxhighlight>
Output
<syntaxhighlight lang="livecode">number of elements: 3
length of item 3: 5
keys: key numbers
abc
key 1</syntaxhighlight>
 
=={{header|Logo}}==
[[UCB Logo]] has "property lists" which associate names with values. They have their own namespace.
<syntaxhighlight 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]</syntaxhighlight>
 
=={{header|LOLCODE}}==
BUKKITs are associative arrays
<syntaxhighlight lang="lolcode">HAI 1.2
I HAS A Hash ITZ A BUKKIT
Hash HAS A key1 ITZ "val1" BTW This works for identifier-like keys, like obj.key in JavaScript
Hash HAS A SRS "key-2" ITZ 1 BTW Non-identifier keys need the SRS
VISIBLE Hash'Z SRS "key-2"
KTHXBYE
</syntaxhighlight>
{{Out}}
<pre>1</pre>
 
=={{header|Lua}}==
Lua tables are Hashes
<syntaxhighlight lang="lua">hash = {}
hash[ "key-1" ] = "val1"
hash[ "key-2" ] = 1
hash[ "key-3" ] = {}</syntaxhighlight>
Returns nil on unknown key.
 
=={{header|M2000 Interpreter}}==
Μ2000 has Inventory object to use it as a Map. All keys converted to strings. If a key has no value then key is the value until we place one. A special type of Inventory is the Inventory Queue, where we can use same keys, and we can't delete except from the last append.
<syntaxhighlight lang="m2000 interpreter">
Inventory A="100":=1, "200":=5, 10:=500, 20:="Hello There"
Print len(A)
Print A(100)=1, A(200)=5, A$(20)="Hello There"
Return A, 100:=3, 200:=7
\\ print all elements
Print A
For i=0 to Len(A)-1 {
\\ Key, Value by current order (using !)
Print Eval$(A, i), A$(i!)
}
\\ Iterator
Append A, "End":=5000
N=Each(A)
While N {
Print Eval$(A, N^), A$(N^!)
}
Print Len(A)=5
Delete A, "100", 10, 20
Print Len(A)=2
If Exist(A, "End") Then Print Eval(A)=5000
 
</syntaxhighlight>
 
=={{header|Maple}}==
Maple tables are hashed arrays. A table can be constructed by using the table constructor.
<syntaxhighlight 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</syntaxhighlight>
New entries are added by assignment.
<syntaxhighlight lang="maple">> T[ "bar" ] := 2;
T["bar"] := 2
 
> T[ "bar" ];
2</syntaxhighlight>
Entries can be removed as follows.
<syntaxhighlight lang="maple">> T[ "foo" ] := evaln( T[ "foo" ] );
T["foo"] := T["foo"]
 
> T[ "foo" ];
T["foo"]</syntaxhighlight>
(The latter output indicates that T["foo"] is an unassigned name.)
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<syntaxhighlight lang="mathematica">a[2] = "string"; a["sometext"] = 23;</syntaxhighlight>
 
=={{header|MATLAB}} / {{header|Octave}}==
 
===MATLAB/Octave: structs===
Associative arrays are called structs. The following methods of creating hash are equivalent.
 
<syntaxhighlight lang="matlab"> hash.a = 1;
hash.b = 2;
hash.C = [3,4,5]; </syntaxhighlight>
alternatively
<syntaxhighlight lang="matlab"> hash = [];
hash = setfield(hash,'a',1);
hash = setfield(hash,'b',2);
hash = setfield(hash,'C',[3,4,5]); </syntaxhighlight>
or
<syntaxhighlight lang="matlab"> hash.('a') = 1;
hash.('b') = 2;
hash.('C') = [3,4,5]; </syntaxhighlight>
 
<pre>>> disp(hash)
scalar structure containing the fields:
a = 1
b = 2
C =
 
3 4 5</pre>
 
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.
<syntaxhighlight lang="matlab">m = containers.Map({'a' 'b' 'C'}, [1 2 3]);</syntaxhighlight>
is equivalent to
<syntaxhighlight lang="matlab">m = containers.Map;
m('a') = 1;
m('b') = 2;
m('C') = 3;</syntaxhighlight>
since the KeyType defaults to 'char'. For numeric keys, the key and value types must be specified at creation.
<syntaxhighlight lang="matlab">m = containers.Map([51 72 37], {'fiftyone' 'seventytwo' 'thirtyseven'});</syntaxhighlight>
is equivalent to
<syntaxhighlight lang="matlab">m = containers.Map('KeyType', 'double', 'ValueType', 'any');
m(51) = 'fiftyone';
m(72) = 'seventytwo';
m(37) = 'thirtyseven';</syntaxhighlight>
Usage:
<pre>>> m = containers.Map([51 72 37], {'fiftyone' 'seventytwo' 'thirtyseven'});
>> keys(m)
 
ans =
 
[37] [51] [72]
 
>> values(m)
 
ans =
 
'thirtyseven' 'fiftyone' 'seventytwo'</pre>
 
=={{header|Maxima}}==
<syntaxhighlight lang="maxima">/* No need to declare anything, undeclared arrays are hashed */
 
h[1]: 6;
h[9]: 2;
 
arrayinfo(h);
[hashed, 1, [1], [9]]</syntaxhighlight>
 
=={{header|min}}==
{{works with|min|0.19.6}}
<syntaxhighlight lang="min">{1 :one 2 :two 3 :three}</syntaxhighlight>
 
=={{header|MiniScript}}==
A map literal in MiniScript is enclosed in curly braces, with key:value pairs separated by commas. Keys and values may be any type. Retrieval or assignment is by putting the key in square brackets. As syntactic sugar, when a string key follows the rules of a MiniScript identifier (starts with a letter and contains only letters, numbers, and underscores), you may also access it with dot syntax.
<syntaxhighlight lang="miniscript">map = { 3: "test", "foo": 42 }
 
print map[3]
map[3] = "more tests"
print map[3]
print map["foo"]
print map.foo // same as map["foo"] (only for string keys that are valid identifiers)
</syntaxhighlight>
 
=={{header|Nemerle}}==
This demonstrates two of several constructors, initializing the hashtable with a list of tuples or just specifying an initial capacity.
<syntaxhighlight 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]);
}
}</syntaxhighlight>
 
=={{header|NetRexx}}==
<syntaxhighlight 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</syntaxhighlight>
 
{{out}}
<pre>
&lt;hash key="0" value="." /&gt;
&lt;hash key="key0" value="value0" /&gt;
</pre>
 
=={{header|Nim}}==
<syntaxhighlight lang="nim">import tables
 
var
hash = initTable[string, int]() # empty hash table
hash1: Table[string, int] # empty hash table (implicit initialization).
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["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
==[[PHP]]==
for key in hash.values:
[[Category:PHP]]
echo key</syntaxhighlight>
{{out}}
<pre>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</pre>
 
=={{header|Oberon-2}}==
$array = array();
{{works with| oo2c Version 2}}
$array['foo'] = 'bar';
<syntaxhighlight lang="oberon2">
$array['bar'] = 'foo';
MODULE AssociativeArray;
IMPORT
ADT:Dictionary,
Object:Boxed,
Out;
TYPE
Key = STRING;
Value = Boxed.LongInt;
VAR
echo($array['foo']); // bar
assocArray: Dictionary.Dictionary(Key,Value);
echo($array['moo']); // Undefined index
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.
 
</syntaxhighlight>
//alternative (inline) way
$array2 = array('fruit'=>'apple, 'price'=>12.96, 'colour'=>'green');
 
=={{header|Objeck}}==
==[[Python]]==
Object parameters must be implicitly casted to the types expected by the method that's called.
[[Category:Python]]
Hashes are a built-in type called dictionaries (or mappings) in Python.
 
=== Associative map===
hash = dict() # 'dict' is the dictionary type.
<syntaxhighlight lang="objeck">
hash = dict(red="FF0000", green="00FF00", blue="0000FF")
# create map
hash = { 'key1':1, 'key2':2, }
map := StringMap->New();
value = hash[key]
# 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();
</syntaxhighlight>
 
===Hash table===
Numerous methods exist for the mapping type http://docs.python.org/lib/typesmapping.html
<syntaxhighlight 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();
</syntaxhighlight>
 
=={{header|Objective-C}}==
==[[Ruby]]==
{{works with|Cocoa}} and {{works with|GNUstep}}
[[Category:Ruby]]
#a hash object that returns nil for unknown keys
hash={}
hash[666]='devil'
hash[777] # => nil
hash[666] # => 'devil'
 
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.
#a hash object that returns 'unknown key' for unknown keys
<syntaxhighlight lang="objc">NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
hash=Hash.new('unknown key')
@"Joe Doe", @"name",
hash[666]='devil'
[NSNumber numberWithUnsignedInt:42], @"age",
hash[777] # => 'unknown key'
[NSNull null], @"extra",
hash[666] # => 'devil'
nil];</syntaxhighlight>
 
The same as the above with the new literal syntax in clang 3.1+ / Apple LLVM Compiler 4.0+ (XCode 4.4+) :
#a hash object that returns "unknown key #{key}" for unknown keys
<syntaxhighlight lang="objc">NSDictionary *dict = @{
hash=Hash.new{|h,k|h[k]="unknown key #{k}"}
@"name": @"Joe Doe",
hash[666]='devil'
@"age": @42,
hash[777] # => 'unknown key 777'
@"extra": [NSNull null],
hash[666] # => 'devil'
};</syntaxhighlight>
 
To create a mutable dictionary, use NSMutableDictionary:
<syntaxhighlight lang="objc">NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:@"Joe Doe" forKey:@"name"];
[dict setObject:[NSNumber numberWithInt:42] forKey:@"age"];</syntaxhighlight>
 
You can access value with objectForKey:. If a key does not exists, nil is returned.
<syntaxhighlight lang="objc">NSString *name = [dict objectForKey:@"name"];
unsigned age = [dict objectForKey:@"age"] unsignedIntValue];
id missing = [dict objectForKey:@"missing"];</syntaxhighlight>
 
=={{header|OCaml}}==
===Hash table===
A simple idiom to create a hash table mapping strings to integers:
<syntaxhighlight lang="ocaml">let hash = Hashtbl.create 0;;
List.iter (fun (key, value) -> Hashtbl.add hash key value)
["foo", 5; "bar", 10; "baz", 15];;</syntaxhighlight>
To retrieve a value:
<syntaxhighlight lang="ocaml">let bar = Hashtbl.find hash "bar";; (* bar = 10 *)</syntaxhighlight>
To retrieve a value, returning a default if the key is not found:
<syntaxhighlight lang="ocaml">let quux = try Hashtbl.find hash "quux" with Not_found -> some_value;;</syntaxhighlight>
 
===Binary tree===
A simple idiom to create a persistent binary tree mapping strings to integers:
<syntaxhighlight 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]
;;</syntaxhighlight>
To retrieve a value:
<syntaxhighlight lang="ocaml">let bar = StringMap.find "bar" map;; (* bar = 10 *)</syntaxhighlight>
To retrieve a value, returning a default if the key is not found:
<syntaxhighlight lang="ocaml">let quux = try StringMap.find "quux" map with Not_found -> some_value;;</syntaxhighlight>
===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.
<syntaxhighlight 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")</syntaxhighlight>
 
=={{header|Ol}}==
Associative arrays in Otus Lisp has name "fixed function" (aka "ff") and fully conforms the functional paradigm. It means that there are no ability to change the existing associative array, only get new changed one.
 
You can use only values as keys (atomic numbers, constants) and, as exception, symbols (symbols are references, but unique). No strings, lists, vectors and other objects can be used directly. In such cases use hashes or similar mechanisms.
 
<syntaxhighlight lang="scheme">
;;; empty associative array
#empty
; or short form
#e
 
;;; creating the new empty associative array
(define empty-map #empty)
 
;;; creating associative array with values
(define my-map (pairs->ff '(
(1 . 100)
(2 . 200)
(7 . 777))))
;;; or in short form (available from Ol version 2.1)
(define my-map {
1 100
2 200
7 777})
 
;;; add new key-value pair to the existing associative array
(define my-new-map (put my-map 'the-key 'the-value))
 
;;; print our arrays
(print empty-map)
; ==> #()
 
(print my-map)
; ==> #((1 . 100) (2 . 200) (7 . 777))
 
(print my-new-map)
; ==> #((1 . 100) (2 . 200) (7 . 777) (the-key . the-value))
</syntaxhighlight>
 
=={{header|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:
<syntaxhighlight lang="oorexx">map = .directory~new
map["foo"] = 5
map["bar"] = 10
map["baz"] = 15
map["foo"] = 6
</syntaxhighlight>
"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:
<syntaxhighlight lang="oorexx">item = map["foo"] -- => 6
item = map["invalid"] -- => .nil</syntaxhighlight>
Note that it is possible to put <code>.nil</code> as a value, so <code>.nil</code> being returned as a value is not sufficient for determining that the key is not in the collection. There is a <code>hasIndex</code> method for that.
 
Iterate over keys:
<syntaxhighlight lang="oorexx">loop key over map
say key
end
</syntaxhighlight>
Iterate over values:
<syntaxhighlight lang="oorexx">loop value over map~allItems
say value
end
</syntaxhighlight>
Iterate over key, value pairs:
<syntaxhighlight lang="oorexx">
s = map~supplier
loop while s~available
say s~index "=>" s~item
s~next
end
</syntaxhighlight>
 
=={{header|OxygenBasic}}==
Not very efficient but the 'find' method could be optimised very easily.
<syntaxhighlight 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
</syntaxhighlight>
 
=={{header|Oz}}==
A mutable map is called a 'dictionary' in Oz:
<syntaxhighlight lang="oz">declare
Dict = {Dictionary.new}
in
Dict.foo := 5
Dict.bar := 10
Dict.baz := 15
Dict.foo := 20
 
{Inspect Dict}</syntaxhighlight>
 
'Records' can be consideres immutable maps:
<syntaxhighlight lang="oz">declare
Rec = name(foo:5 bar:10 baz:20)
in
{Inspect Rec}</syntaxhighlight>
 
=={{header|PARI/GP}}==
{{works with|PARI/GP|2.8.1+}}
 
GP's associative arrays are called maps, and can be created like so:
<syntaxhighlight lang="parigp">M = Map();</syntaxhighlight>
They can be used as follows:
<syntaxhighlight 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");</syntaxhighlight>
 
In PARI the commands are <code>gtomap</code>, <code>mapput</code>, <code>mapget</code>, <code>mapisdefined</code>, and <code>mapdelete</code>. You can also use the solutions in [[Associative arrays/Creation/C]].
 
=={{header|Perl}}==
===Hash===
Definition:
<syntaxhighlight 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',
);</syntaxhighlight>
 
Use:
<syntaxhighlight lang="perl">print $hash{key1};
 
$hash{key1} = 'val1';
 
@hash{'key1', 'three'} = ('val1', -238.83);</syntaxhighlight>
===HashRef===
Definition:
<syntaxhighlight lang="perl">my $hashref = {
key1 => 'val1',
'key-2' => 2,
three => -238.83,
4 => 'val3',
}</syntaxhighlight>
 
Use:
<syntaxhighlight lang="perl">print $hashref->{key1};
 
$hashref->{key1} = 'val1';
 
@{$hashref}{('key1', 'three')} = ('val1', -238.83);</syntaxhighlight>
 
===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 <code>tie</code> modules implement keys of other types, usually by constructing underlying string keys of suitable nature. For example <code>Tie::RefHash</code> allows objects (blessed or unblessed) as keys.
 
=={{header|Phix}}==
Associative arrays are supported via just eight simple routines, with no specialised syntax.<br>
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).
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #7060A8;">setd</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"one"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">setd</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"duo"</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">setd</span><span style="color: #0000FF;">({</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"six"</span><span style="color: #0000FF;">})</span>
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">getd</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"one"</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- shows 1</span>
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">getd</span><span style="color: #0000FF;">({</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">})</span> <span style="color: #000080;font-style:italic;">-- shows {5,"six"}</span>
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">getd</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- shows "duo"</span>
<span style="color: #7060A8;">deld</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">getd</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- shows 0</span>
<!--</syntaxhighlight>-->
 
=={{header|Phixmonti}}==
<syntaxhighlight lang="phixmonti">include ..\Utilitys.pmt
 
def getd /# dict key -- dict data #/
swap 1 get rot find nip
dup if
swap 2 get rot get nip
else
drop "Unfound"
endif
enddef
 
def setd /# dict ( key data ) -- dict #/
1 get var ikey
2 get var idata
drop
1 get ikey find var p drop
p if
2 get idata p set 2 set
else
2 get idata 0 put 2 set
1 get ikey 0 put 1 set
endif
enddef
 
( ( ) ( ) )
 
( 1 "one" ) setd
( "two" 2 ) setd
( PI PI ) setd
 
1 getd print nl
"two" getd print nl
PI getd tostr print nl
3 getd print
</syntaxhighlight>
 
=={{header|PHP}}==
<syntaxhighlight 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</syntaxhighlight>
 
===Iterate over key/value===
<syntaxhighlight lang="php">foreach($array as $key => $value)
{
echo echo('"Key: '.$key.' Value: '.$value)";
}</syntaxhighlight>
}
 
=={{header|Picat}}==
==[[Perl]]==
Associative arrays are called "map" in Picat.
[[Category:Perl]]
<syntaxhighlight lang="picat">go =>
'''Interpeter:''' Perl
 
% Create an empty map
===Defining a Hash===
Map = new_map(),
println(Map),
 
% add some data
# using => key does not need to be quoted unless it contains special chars
Map.put(a,1),
my %hash = (
Map.put("picat",2),
key1 => 'val1',
Map.put("picat",3), % overwrite values
'key-2' => 2,
% Add a new value (a long list of different stuff)
three => -238.83,
Map.put([a,list,of,different,"things",[including, lists],3.14159],2),
4 => 'val3',
println(Map),
);
 
println(a=Map.get(a)), % get a value
println(b=Map.get(b,'default value')), % the second argument to get/2 is the default value
 
% create a map from a list of values
Map2 = new_map([K=V : {K,V} in zip([a,b,c,d,e,f,g,h],1..8)]),
println(Map2),
println(h=Map2.get(h)),
 
% Check if there is a value in the map
if not Map2.has_key(z) then
println("no key 'z'")
end,
 
% keys() and value() returns unsorted list of elements
% so we sort them.
println(keys=Map2.keys().sort()),
println(values=Map2.values().sort()),
 
% Print the values for the keys that are even
println([K : K=V in Map2, V mod 2=0].sort),
 
nl.
</syntaxhighlight>
 
{{out}}
<pre>(map)[]
(map)[a = 1,picat = 3,[a,list,of,different,things,[including,lists],3.14159] = 2]
a = 1
b = default value
(map)[b = 2,a = 1,e = 5,h = 8,f = 6,g = 7,d = 4,c = 3]
h = 8
no key 'z'
keys = abcdefgh
values = [1,2,3,4,5,6,7,8]
bdfh</pre>
 
=={{header|PicoLisp}}==
Here we use symbol properties. Other possiblities could be
[http://software-lab.de/doc/refI.html#idx index trees] or
[http://software-lab.de/doc/refA.html#assoc association lists].
 
<syntaxhighlight 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</syntaxhighlight>
 
=={{header|Pike}}==
Pike provides a built in type called ''mapping'' for associative
arrays. Any data type including user created classes can be used as
indices (aka keys in some other languages) and values.
 
There are two main ways of indexing a mapping; a[b] or a->b, with
variants for "safe" indexing that will not throw error when indexing
nonexistent indices. See the documentation for
[https://pike.lysator.liu.se/docs/man/chapter_4.html#4.5 indexing].
 
''indices()'' and ''values()'' can be used to enumerate the contents
of an existing mapping.
<syntaxhighlight lang="pike">
mapping m = ([ "apple": "fruit", 17: "seventeen" ]);
write("indices: %O\nvalues: %O\n17: %O\n",
indices(m),
values(m),
m[17]);
</syntaxhighlight>
{{Out}}
<pre>
indices: ({
17,
"apple"
})
values: ({
"seventeen",
"fruit"
})
17: "seventeen"
</pre>
 
Since any data type can be used nested structures of arbitrary size can
be constructed.
<syntaxhighlight lang="pike">
mapping m2 = ([ "car": ([ "ford":17, "volvo":42 ]) ]);
write("#ford: %O, #volvo: %O\n",
m2->car->ford,
m2["car"]["volvo"]);
</syntaxhighlight>
{{Out}}
<pre>
#ford: 17, #volvo: 42
</pre>
 
=={{header|PL/I}}==
<syntaxhighlight 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;</syntaxhighlight>
{{out}}
<pre>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< </pre>
 
=={{header|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:-
<syntaxhighlight 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;
/</syntaxhighlight>
 
=={{header|Pop11}}==
<syntaxhighlight 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);</syntaxhighlight>
 
=={{header|PostScript}}==
<syntaxhighlight lang="postscript">
<</a 100 /b 200 /c 300>>
dup /a get =
</syntaxhighlight>
 
=={{header|Potion}}==
<syntaxhighlight lang="potion">mydictionary = (red=0xff0000, green=0x00ff00, blue=0x0000ff)
 
redblue = "purple"
mydictionary put(redblue, 0xff00ff)
 
255 == mydictionary("blue")
65280 == mydictionary("green")
16711935 == mydictionary("purple")</syntaxhighlight>
 
=={{header|PowerShell}}==
An empty hash table can be created with:
<syntaxhighlight lang="powershell">$hashtable = @{}</syntaxhighlight>
A hash table can be initialized with key/value pairs:
<syntaxhighlight lang="powershell">$hashtable = @{
"key1" = "value 1"
key2 = 5 # if the key name has no spaces, no quotes are needed.
}</syntaxhighlight>
Individual values can be assigned or replaced by either using a property-style access method or indexing into the table with the given key:
<syntaxhighlight 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</syntaxhighlight>
NB. PowerShell compares strings as case-insensitive, that means the hashtable keys 'a' and 'A' are considered the same key. This happens when @{} is turned into a hashtable, but can be overridden by an explicit long-form:
<syntaxhighlight lang="powershell"># Case insensitive keys, both end up as the same key:
$h=@{}
$h['a'] = 1
$h['A'] = 2
$h
 
Name Value
---- -----
a 2
 
# Case sensitive keys:
$h = New-Object -TypeName System.Collections.Hashtable
$h['a'] = 1
$h['A'] = 2
$h
 
Name Value
---- -----
A 2
a 1 </syntaxhighlight>
Similarly, values can be retrieved using either syntax:
<syntaxhighlight lang="powershell">$hashtable.key1 # value 1
$hashtable['key2'] # 5</syntaxhighlight>
It is common to see a hashtable literal used to create an object, by casting it to a new type:
<syntaxhighlight lang="powershell">$obj = [PSCustomObject]@{
"key1" = "value 1"
key2 = 5
}</syntaxhighlight>
This is a convenience syntax, has less code and runs faster than other ways to create objects.
 
=={{header|Prolog}}==
We use the facts table for this purpose.
<syntaxhighlight lang="prolog">
mymap(key1,value1).
mymap(key2,value2).
 
?- mymap(key1,V).
V = value1
</syntaxhighlight>
 
=={{header|PureBasic}}==
Hashes are a built-in type called Map in Purebasic.
 
<syntaxhighlight lang="purebasic">NewMap dict.s()
dict("country") = "Germany"
Debug dict("country")</syntaxhighlight>
 
=={{header|Python}}==
Hashes are a built-in type called dictionaries (or mappings) in Python.
 
<syntaxhighlight 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]</syntaxhighlight>
 
Numerous methods exist for the mapping type https://docs.python.org/3/library/stdtypes.html#mapping-types-dict
 
<syntaxhighlight 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</syntaxhighlight>
 
Note: Python dictionary keys can be of any arbitrary "hashable" type. The following contains several distinct key value pairs:
 
<syntaxhighlight lang="python">myDict = { '1': 'a string', 1: 'an integer', 1.0: 'a floating point number', (1,): 'a tuple' }</syntaxhighlight>
 
(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.
 
=={{header|R}}==
 
R lacks a native representation of key-value pairs, but different structures allow named elements, which provide similar functionality.
 
=== environment example ===
 
<syntaxhighlight lang="r">> env <- new.env()
> env[["x"]] <- 123
> env[["x"]]</syntaxhighlight>
<pre>[1] 123</pre>
<syntaxhighlight lang="r">> index <- "1"
> env[[index]] <- "rainfed hay"
> env[[index]]</syntaxhighlight>
<pre>[1] "rainfed hay"</pre>
<syntaxhighlight lang="r">> env[["1"]]</syntaxhighlight>
<pre>[1] "rainfed hay"</pre>
<syntaxhighlight lang="r">> env</syntaxhighlight>
<pre><environment: 0xb7cd560></pre>
<syntaxhighlight lang="r">> print(env)</syntaxhighlight>
<pre><environment: 0xb7cd560></pre>
 
=== vector example ===
 
<syntaxhighlight lang="r">> x <- c(hello=1, world=2, "!"=3)
> print(x)</syntaxhighlight>
<pre>hello world !
1 2 3</pre>
<syntaxhighlight lang="r">> print(names(x))</syntaxhighlight>
<pre>[1] "hello" "world" "!"</pre>
<syntaxhighlight lang="r">print(unname(x))</syntaxhighlight>
<pre>[1] 1 2 3</pre>
 
=== list example ===
 
<syntaxhighlight lang="r">> a <- list(a=1, b=2, c=3.14, d="xyz")
> print(a)</syntaxhighlight>
<pre>$a
[1] 1
 
$b
[1] 2
 
$c
[1] 3.14
 
$d
[1] "xyz"</pre>
<syntaxhighlight lang="r">> print(names(a))</syntaxhighlight>
<pre>[1] "a" "b" "c" "d"</pre>
<syntaxhighlight lang="r">> print(unname(a))</syntaxhighlight>
<pre>[[1]]
[1] 1
 
[[2]]
[1] 2
 
[[3]]
[1] 3.14
 
[[4]]
[1] "xyz"</pre>
 
=={{header|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.
 
<syntaxhighlight 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
</syntaxhighlight>
 
=={{header|Raku}}==
(formerly Perl 6)
{{works with|Rakudo|2018.03}}
 
The fatarrow, <code>=></code>, is no longer just a quoting comma; it now constructs a <code>Pair</code> object. But you can still define a hash with an ordinary list of even length.
 
<syntaxhighlight lang="raku" line>my %h1 = key1 => 'val1', 'key-2' => 2, three => -238.83, 4 => 'val3';
my %h2 = 'key1', 'val1', 'key-2', 2, 'three', -238.83, 4, 'val3';
 
# Creating a hash from two lists using a metaoperator.
 
my @a = 1..5;
my @b = 'a'..'e';
my %h = @a Z=> @b;
 
# 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 Raku's qw (shortcut < ... >) now auto-subscripts.
 
say %h1{'key1'};
say %h1<key1>;
%h1<key1> = 'val1';
%h1<key1 three> = 'val1', -238.83;
 
# Special syntax is no longer necessary to access a hash stored in a scalar.
 
my $h = {key1 => 'val1', 'key-2' => 2, three => -238.83, 4 => 'val3'};
say $h<key1>;
 
# Keys are of type Str or Int by default. The type of the key can be provided.
 
my %hash{Any}; # same as %hash{*}
class C {};
my %cash{C};
%cash{C.new} = 1;</syntaxhighlight>
 
=={{header|Raven}}==
<syntaxhighlight 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</syntaxhighlight>
 
Null is returned for unknown keys.
 
 
=={{header|Relation}}==
<syntaxhighlight lang="relation">
relation key, value
insert "foo", "bar"
insert "bar", "foo"
insert "fruit", "apple"
assert unique key
print
select key == "fruit"
print
</syntaxhighlight>
 
'''assert''' will show an error, if a key is used twice. However, it not stop the insertion.
 
{| border=1
|-
! key !! value
|-
| foo || bar
|-
| bar || foo
|-
| fruit || apple
|}
 
{| border=1
|-
! key !! value
|-
| fruit || apple
|}
 
=={{header|Retro}}==
<syntaxhighlight lang="retro">with hashTable'
hashTable constant table
 
table %{ first = 100 }%
table %{ second = "hello, world!" keepString %}
 
table @" first" putn
table @" second" puts</syntaxhighlight>
 
=={{header|REXX}}==
===version 1===
Associative arrays are called ''stem variables'' in Rexx.
<syntaxhighlight 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 */</syntaxhighlight>
{{out}}
<pre>stem.key0= .
stem.key1= value0</pre>
 
===version 2===
<syntaxhighlight 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.*/</syntaxhighlight>
{{out}}
<pre>
capital of California is Sacramento
capital of Oklahoma is [not defined yet]
capital of Rhode Island and Providence Plantations is Providence
</pre>
 
=={{header|Ring}}==
<syntaxhighlight lang="ring">
# Project Associative array/Creation
 
myarray = [["one",1],
["two",2],
["three",3]]
see find(myarray,"two",1) + nl
see find(myarray,2,2) + nl
</syntaxhighlight>
Output:
<pre>
2
2
</pre>
 
=={{header|RLaB}}==
Associative arrays are called ''lists'' in RLaB.
<syntaxhighlight 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.
 
</syntaxhighlight>
 
=={{header|Ruby}}==
===Hash literals===
Ruby has literal syntax for Hash objects.
 
A Hash with symbols as keys:
<syntaxhighlight lang="ruby">
{:name => 'Zeus', :planet => 'Jupiter'}
</syntaxhighlight>
 
Shorthand for symbol keys:
 
<syntaxhighlight lang="ruby">
{name: 'Zeus', planet: 'Jupiter'}
</syntaxhighlight>
 
A Hash with keys and values of arbitrary types:
 
<syntaxhighlight lang="ruby">
{1 => 'two', three: 4}
</syntaxhighlight>
 
An empty Hash:
 
<syntaxhighlight lang="ruby">
{}
</syntaxhighlight>
 
===Customizing the default value===
 
A Hash object that returns [[nil]] for unknown keys:
<syntaxhighlight lang="ruby">hash = {}
hash[666] = 'devil'
hash[777] # => nil
hash[666] # => 'devil'</syntaxhighlight>
 
A Hash object that returns 'unknown key' for unknown keys:
<syntaxhighlight lang="ruby">hash = Hash.new('unknown key')
hash[666] = 'devil'
hash[777] # => 'unknown key'
hash[666] # => 'devil'</syntaxhighlight>
 
A Hash object that returns "unknown key #{key}" for unknown keys:
<syntaxhighlight lang="ruby">hash = Hash.new { |h, k| "unknown key #{k}" }
hash[666] = 'devil'
hash[777] # => 'unknown key 777'
hash[666] # => 'devil'</syntaxhighlight>
 
A Hash object that adds "key #{key} was added at #{Time.now}" to the hash the first time an unknown key is seen:
<syntaxhighlight 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'</syntaxhighlight>
 
=={{header|Rust}}==
<syntaxhighlight 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);
}</syntaxhighlight>
 
=={{header|Sather}}==
<syntaxhighlight 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;
</syntaxhighlight>
 
=={{header|Scala}}==
<syntaxhighlight 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</syntaxhighlight>
 
<syntaxhighlight 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</syntaxhighlight>
 
<syntaxhighlight 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)</syntaxhighlight>
 
<syntaxhighlight 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)</syntaxhighlight>
 
=={{header|Scheme}}==
 
Scheme has association lists (alists), which are inefficient, ordered maps with arbitrary keys and values.
<syntaxhighlight lang="scheme">(define my-dict '((a b) (1 hello) ("c" (a b c)))
(assoc 'a my-dict) ; evaluates to '(a b)</syntaxhighlight>
 
 
Hash tables are provided by SRFI-69 [http://srfi.schemers.org/srfi-69/srfi-69.html]. Many Scheme implementation also provide native hash tables.
 
<syntaxhighlight lang="scheme">(define my-alist '((a b) (1 hello) ("c" (a b c)))
(define my-hash (alist->hash-table my-alist))</syntaxhighlight>
 
The R6RS standard specifies support for hashtables in the [http://www.r6rs.org/final/html/r6rs-lib/r6rs-lib-Z-H-14.html#node_chap_13 standard libraries] document.
 
<syntaxhighlight 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))</syntaxhighlight>
 
=== A ''persistent'' associative array from scratch ===
{{works with|CHICKEN|5.3.0}}
{{libheader|r7rs}}
{{libheader|srfi-1}}
{{libheader|srfi-151}}
 
Most implementations of associative arrays—including those for Scheme—are for ‘''mutable''’ arrays, whose previous values are effectively lost whenever an insertion is done. Here instead is a ''persistent'' (‘''immutable''’) implementation, using code from [[AVL_tree#Scheme|the AVL Tree task]]. (So performance will be on average logarithmic. Just be aware of that.)
 
That there are so many implementations of associative arrays for Scheme is partly because making an implementation from scratch is fairly easy. But many approaches are difficult to use if the goal is ''persistent'' associative arrays. For instance, if you use a classical hash table, inserting an association would require copying an entire array.
 
Associate arrays are not part of the Scheme language itself, but are compiler/interpreter or library add-ons. So I feel justified in presenting this sketch of yet another library add-on.
 
<syntaxhighlight lang="scheme">(cond-expand
(r7rs)
(chicken (import r7rs)))
 
(define-library (avl-trees)
 
;;
;; This library implements ‘persistent’ (that is, ‘immutable’) AVL
;; trees for R7RS Scheme.
;;
;; References:
;;
;; * Niklaus Wirth, 1976. Algorithms + Data Structures =
;; Programs. Prentice-Hall, Englewood Cliffs, New Jersey.
;;
;; * Niklaus Wirth, 2004. Algorithms and Data Structures. Updated
;; by Fyodor Tkachov, 2014.
;;
;; THIS IS A TRIMMED-DOWN VERSION OF MY SOLUTION TO THE AVL TREES
;; TASK: https://rosettacode.org/wiki/AVL_tree#Scheme
;;
 
(export avl)
(export avl?)
(export avl-empty?)
(export avl-insert)
(export avl-search-values)
(export avl-check-usage)
 
(import (scheme base))
(import (scheme case-lambda))
(import (scheme process-context))
(import (scheme write))
 
(begin
 
(define-syntax avl-check-usage
(syntax-rules ()
((_ pred msg)
(or pred (usage-error msg)))))
 
(define-record-type <avl>
(%avl key data bal left right)
avl?
(key %key)
(data %data)
(bal %bal)
(left %left)
(right %right))
 
(define (avl)
(%avl #f #f #f #f #f))
 
(define (avl-empty? tree)
(avl-check-usage
(avl? tree)
"avl-empty? expects an AVL tree as argument")
(not (%bal tree)))
 
(define (avl-search-values pred<? tree key)
;; Return two values: the data matching the key, or #f is the
;; key is not found; and a second value that is either #f or #t,
;; depending on whether the key is found.
(define (search p)
(if (not p)
(values #f #f)
(let ((k (%key p)))
(cond ((pred<? key k) (search (%left p)))
((pred<? k key) (search (%right p)))
(else (values (%data p) #t))))))
(avl-check-usage
(procedure? pred<?)
"avl-search-values expects a procedure as first argument")
(if (avl-empty? tree)
(values #f #f)
(search tree)))
 
(define (avl-insert pred<? tree key data)
 
(define (search p fix-balance?)
(cond
((not p)
;; The key was not found. Make a new node and set
;; fix-balance?
(values (%avl key data 0 #f #f) #t))
 
((pred<? key (%key p))
;; Continue searching.
(let-values (((p1 fix-balance?)
(search (%left p) fix-balance?)))
(cond
((not fix-balance?)
(let ((p^ (%avl (%key p) (%data p) (%bal p)
p1 (%right p))))
(values p^ #f)))
(else
;; A new node has been inserted on the left side.
(case (%bal p)
((1)
(let ((p^ (%avl (%key p) (%data p) 0
p1 (%right p))))
(values p^ #f)))
((0)
(let ((p^ (%avl (%key p) (%data p) -1
p1 (%right p))))
(values p^ fix-balance?)))
((-1)
;; Rebalance.
(case (%bal p1)
((-1)
;; A single LL rotation.
(let* ((p^ (%avl (%key p) (%data p) 0
(%right p1) (%right p)))
(p1^ (%avl (%key p1) (%data p1) 0
(%left p1) p^)))
(values p1^ #f)))
((0 1)
;; A double LR rotation.
(let* ((p2 (%right p1))
(bal2 (%bal p2))
(p^ (%avl (%key p) (%data p)
(- (min bal2 0))
(%right p2) (%right p)))
(p1^ (%avl (%key p1) (%data p1)
(- (max bal2 0))
(%left p1) (%left p2)))
(p2^ (%avl (%key p2) (%data p2) 0
p1^ p^)))
(values p2^ #f)))
(else (internal-error))))
(else (internal-error)))))))
 
((pred<? (%key p) key)
;; Continue searching.
(let-values (((p1 fix-balance?)
(search (%right p) fix-balance?)))
(cond
((not fix-balance?)
(let ((p^ (%avl (%key p) (%data p) (%bal p)
(%left p) p1)))
(values p^ #f)))
(else
;; A new node has been inserted on the right side.
(case (%bal p)
((-1)
(let ((p^ (%avl (%key p) (%data p) 0
(%left p) p1)))
(values p^ #f)))
((0)
(let ((p^ (%avl (%key p) (%data p) 1
(%left p) p1)))
(values p^ fix-balance?)))
((1)
;; Rebalance.
(case (%bal p1)
((1)
;; A single RR rotation.
(let* ((p^ (%avl (%key p) (%data p) 0
(%left p) (%left p1)))
(p1^ (%avl (%key p1) (%data p1) 0
p^ (%right p1))))
(values p1^ #f)))
((-1 0)
;; A double RL rotation.
(let* ((p2 (%left p1))
(bal2 (%bal p2))
(p^ (%avl (%key p) (%data p)
(- (max bal2 0))
(%left p) (%left p2)))
(p1^ (%avl (%key p1) (%data p1)
(- (min bal2 0))
(%right p2) (%right p1)))
(p2^ (%avl (%key p2) (%data p2) 0
p^ p1^)))
(values p2^ #f)))
(else (internal-error))))
(else (internal-error)))))))
 
(else
;; The key was found; p is an existing node.
(values (%avl key data (%bal p) (%left p) (%right p))
#f))))
 
(avl-check-usage
(procedure? pred<?)
"avl-insert expects a procedure as first argument")
(if (avl-empty? tree)
(%avl key data 0 #f #f)
(let-values (((p fix-balance?) (search tree #f)))
p)))
 
(define (internal-error)
(display "internal error\n" (current-error-port))
(emergency-exit 123))
 
(define (usage-error msg)
(display "Procedure usage error:\n" (current-error-port))
(display " " (current-error-port))
(display msg (current-error-port))
(newline (current-error-port))
(exit 1))
 
)) ;; end library (avl-trees)
 
 
(define-library (associative-arrays)
 
;;
;; Persistent associative arrays for R7RS Scheme.
;;
;; The story:
;;
;; An implementation of associative arrays, where keys are compared
;; with an ‘equal to’ predicate, typically has three parts:
;;
;; * a hash function, which converts a key to a hash value; and
;; the hash value either has a ‘less than’ predicate or can be
;; put in a radix tree;
;;
;; * a table keyed by the hash values;
;;
;; * a way to resolve hash value collisions.
;;
;; At one extreme is the association list, which can be viewed as
;; having a hash function that *always* collides. At a nearly
;; opposite extreme are ideal hash trees, which never have
;; collisions, but which, towards that end, require hash values to
;; ‘grow’ on the fly.
;;
;; Perhaps the simplest form of associative array having all three
;; parts is ‘separate chaining’: the hash function generates an
;; integer modulo some table size; the table itself is an array of
;; that size; and collisions are resolved by falling back to an
;; association list.
;;
;; Below I use my solution to the AVL Tree task
;; (https://rosettacode.org/wiki/AVL_tree#Scheme) to implement
;; *persistent* (that is, ‘immutable’) associative arrays. The hash
;; function is whatever you want, as long as it produces (what
;; Scheme regards as) a real number. Hash value collisions are
;; resolved by falling back to association lists.
;;
 
(export assoc-array)
(export assoc-array?)
(export assoc-array-set)
(export assoc-array-ref)
 
(import (scheme base))
(import (scheme case-lambda))
(import (scheme write))
(import (avl-trees))
 
(cond-expand
(chicken (import (only (srfi 1) alist-delete)))
;; Insert whatever you need here for your Scheme.
(else))
 
(begin
 
(define-record-type <assoc-array>
(%assoc-array hashfunc pred=? default table)
assoc-array?
(hashfunc %hashfunc)
(pred=? %pred=?)
(default %default)
(table %table))
 
(define assoc-array
;; Create an associative array.
(case-lambda
((hashfunc)
(let ((pred=? equal?)
(default #f))
(assoc-array hashfunc pred=? default)))
((hashfunc pred=?)
(let ((default #f))
(assoc-array hashfunc pred=? default)))
((hashfunc pred=? default)
(%assoc-array hashfunc pred=? default (avl)))))
 
(define (assoc-array-set array key data)
;; Produce a new associative array that is the same as the input
;; array except for the given key-data association. The input
;; array is left unchanged (which is why the procedure is called
;; ‘assoc-array-set’ rather than ‘assoc-array-set!’).
(let ((hashfunc (%hashfunc array))
(pred=? (%pred=? array))
(default (%default array))
(table (%table array)))
(let ((hash-value (hashfunc key)))
;; The following could be made more efficient by combining
;; the ‘search’ and ‘insert’ operations for the AVL tree.
(let*-values
(((alst found?) (avl-search-values < table hash-value)))
(cond
(found?
;; Add a new entry to the association list. Removal of
;; any old associations with the key is not strictly
;; necessary, but without it the associative array will
;; grow every time you replace an
;; association. (Alternatively, you could occasionally
;; clean the associative array of shadowed key
;; associations.)
(let* ((alst (alist-delete key alst pred=?))
(alst `((,key . ,data) . ,alst))
(table (avl-insert < table hash-value alst)))
(%assoc-array hashfunc pred=? default table)))
(else
;; Start a new association list.
(let* ((alst `((,key . ,data)))
(table (avl-insert < table hash-value alst)))
(%assoc-array hashfunc pred=? default table))))))))
 
(define (assoc-array-ref array key)
;; Return the data associated with the key. If the key is not in
;; the table, return the associative array’s default data.
(let* ((hashfunc (%hashfunc array))
(hash-value (hashfunc key)))
(let*-values
(((alst found?)
(avl-search-values < (%table array) hash-value)))
(if found?
(let ((pair (assoc key alst (%pred=? array))))
(if pair
(cdr pair)
(%default array)))
(%default array)))))
 
)) ;; end library (associative-arrays)
 
 
(cond-expand
(DEMONSTRATION
(begin
(import (scheme base))
(import (scheme write))
(import (srfi 151))
(import (associative-arrays))
 
;; I like SpookyHash, but for this demonstration I shall use the
;; simpler ‘ElfHash’ and define it only for strings. See
;; https://en.wikipedia.org/w/index.php?title=PJW_hash_function&oldid=997863283
(define (hashfunc s)
(let ((n (string-length s))
(h 0))
(do ((i 0 (+ i 1)))
((= i n))
(let* ((ch
;; If the character is outside the 8-bit range,
;; probably I should break it into four bytes, each
;; incorporated separately into the hash. For this
;; demonstration, I shall simply discard the higher
;; bits.
(bitwise-and (char->integer (string-ref s i))
#xFF))
(h^ (+ (arithmetic-shift h 4) ch))
(high^ (bitwise-and h^ #xF0000000)))
(unless (zero? high^)
(set! h^
(bitwise-xor h^ (arithmetic-shift high^ -24))))
(set! h (bitwise-and h^ (bitwise-not high^)))))
h))
 
(let* ((a1 (assoc-array hashfunc))
(a2 (assoc-array-set a1 "A" #\A))
(a3 (assoc-array-set a2 "B" #x42)) ; ASCII ‘B’.
(a4 (assoc-array-set a3 "C" "C")))
(write (assoc-array-ref a1 "A")) (newline)
(write (assoc-array-ref a1 "B")) (newline)
(write (assoc-array-ref a1 "C")) (newline)
(write (assoc-array-ref a2 "A")) (newline)
(write (assoc-array-ref a2 "B")) (newline)
(write (assoc-array-ref a2 "C")) (newline)
(write (assoc-array-ref a3 "A")) (newline)
(write (assoc-array-ref a3 "B")) (newline)
(write (assoc-array-ref a3 "C")) (newline)
(write (assoc-array-ref a4 "A")) (newline)
(write (assoc-array-ref a4 "B")) (newline)
(write (assoc-array-ref a4 "C")) (newline))
 
))
(else))</syntaxhighlight>
 
{{out}}
<pre>$ csc -DDEMONSTRATION -R r7rs -X r7rs associative_array-scheme.scm && ./associative_array-scheme
#f
#f
#f
#\A
#f
#f
#\A
66
#f
#\A
66
"C"</pre>
 
It is easy [[Associative_array/Iteration#For_persistent_associative_arrays|to add ''generators'']] to this implementation, by which I mean ‘iterators’ that are themselves executable procedures.
 
(''Afterword''. To be honest, I would not use the term ‘associative array’, because ‘array’ implies uniformly constant time access, which even a traditional hash table generally cannot provide. I would call these things ‘maps’—or, if the word ‘map’ is heavily used for something else [such as Scheme’s '''map''' procedures], then I would call them ‘dictionaries’.)
 
=={{header|Seed7}}==
Seed7 uses the type [http://seed7.sourceforge.net/manual/types.htm#hash hash] to support associative arrays.
 
<syntaxhighlight 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;</syntaxhighlight>
 
=={{header|SenseTalk}}==
Associative arrays in SenseTalk are called property lists, or objects.
<syntaxhighlight lang="sensetalk">put {} into emptyPlist
put an empty property list into emptyPlist2
 
put {first:"Albert", last:"Einstein"} into Einstein
set Einstein's occupation to "Physicist"
put 1879 into Einstein.yearBorn
put "!!!" after the occupation of Einstein
put Einstein
</syntaxhighlight>
{{out}}
<pre>
{first:"Albert", last:"Einstein", occupation:"Physicist!!!", yearBorn:1879}
</pre>
 
=={{header|SETL}}==
Associative arrays (referred to in SETL terminology as <i>maps</i>) are implemented as sets whose only members are tuples of length 2. Create such a set:
<syntaxhighlight lang="setl">m := {['foo', 'a'], ['bar', 'b'], ['baz', 'c']};</syntaxhighlight>
We can then index the set, or map, with the first element of a constituent tuple to return that tuple's second element:
<syntaxhighlight lang="setl">print( m('bar') );</syntaxhighlight>
{{out}}
<pre>b</pre>
If the map might contain more than one value associated with the same key, we can return the set of them (in this instance a unit set because the keys are in fact unique):
<syntaxhighlight lang="setl">print( m{'bar'} );</syntaxhighlight>
{{out}}
<pre>{b}</pre>
 
=={{header|SETL4}}==
<syntaxhighlight lang="setl4">
* Iterate over key-value pairs of a map
 
map = new('map 1:one 2:two 3:three')
visit(domain(map),'expr to evaluate for each member')
visit(range(map),'expr to evaluate for each member')
next
this = next(map) :f(done)
out(show(this) ':' show(get(map,this)) :next)
done
loop(d = domain(map)
next
out('next domain entry',next(d)) :s(next)
done
loop(d = range(map)
next
out('next domain entry',next(d)) :s(next)
done
</syntaxhighlight>
 
=={{header|Sidef}}==
<syntaxhighlight lang="ruby">var hash = Hash(
key1 => 'value1',
key2 => 'value2',
)
 
# Add a new key-value pair
hash{:key3} = 'value3'</syntaxhighlight>
 
=={{header|Slate}}==
<syntaxhighlight lang="slate">Dictionary new*, 'MI' -> 'Michigan', 'MN' -> 'Minnesota'</syntaxhighlight>
# 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',
);
 
=={{header|Smalltalk}}==
===Defining a HashRef===
<syntaxhighlight lang="smalltalk">states := Dictionary new.
states at: 'MI' put: 'Michigan'.
states at: 'MN' put: 'Minnesota'.</syntaxhighlight>
alternative:
<syntaxhighlight lang="smalltalk">Dictionary withAssociations:{ 'MI' -> 'Michigan' . 'MN' -> 'Minnesota'}</syntaxhighlight>
 
=={{header|SNOBOL4}}==
my $hashref = {
<syntaxhighlight lang="snobol4"> t = table()
key1 => 'val1',
t<"red"> = "#ff0000"
'key-2' => 2,
t<"green"> = "#00ff00"
three => -238.83,
t<"blue"> = "#0000ff"
4 => 'val3',
 
output = t<"red">
output = t<"blue">
output = t<"green">
end</syntaxhighlight>
 
=={{header|SQL}}==
<syntaxhighlight 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';
</syntaxhighlight>
 
=={{header|SQL PL}}==
{{works with|Db2 LUW}} version 9.7 or higher.
With SQL PL:
<syntaxhighlight lang="sql pl">
--#SET TERMINATOR @
 
SET SERVEROUTPUT ON @
 
BEGIN
DECLARE TYPE ASSOC_ARRAY AS VARCHAR(20) ARRAY [VARCHAR(20)];
DECLARE HASH ASSOC_ARRAY;
SET HASH['key1'] = 'val1';
SET HASH['key-2'] = 2;
SET HASH['three'] = -238.83;
SET HASH[4] = 'val3';
 
CALL DBMS_OUTPUT.PUT_LINE(HASH['key1']);
CALL DBMS_OUTPUT.PUT_LINE(HASH['key-2']);
CALL DBMS_OUTPUT.PUT_LINE(HASH['three']);
CALL DBMS_OUTPUT.PUT_LINE(HASH[4]);
CALL DBMS_OUTPUT.PUT_LINE(HASH['5']);
END@
</syntaxhighlight>
Output:
<pre>
db2 -td@
db2 => BEGIN
...
db2 (cont.) => END @
END
DB21034E The command was processed as an SQL statement because it was not a
valid Command Line Processor command. During SQL processing it returned:
SQL20439N Array index with value "5" is out of range or does not exist.
SQLSTATE=2202E
 
val1
2
-238.83
val3
</pre>
 
=={{header|Stata}}==
<syntaxhighlight lang="stata">mata
a=asarray_create()
 
// Add entries
asarray(a,"one",1)
asarray(a,"two",2)
 
// Check existence of key
asarray_contains(a,"two")
 
// Get a vector of all keys
asarray_keys(a)
 
// Number of entries
asarray_elements(a)
 
// End Mata session
end</syntaxhighlight>
 
=={{header|Swift}}==
<syntaxhighlight 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]</syntaxhighlight>
 
=={{header|Symsyn}}==
Symsyn implements Hash as a list of strings. Each name/value or key/value pair is stored in another string. The name/value pair is in the format 'name=value', the '=' is reserved.
<syntaxhighlight lang="symsyn">
#+ 'name=bob' $hash | add to hash
#? 'name' $hash $S | find 'name' and return 'bob' in $S
#- 'name' $hash | delete 'name=bob' from hash
</syntaxhighlight>
=={{header|Tcl}}==
All arrays in Tcl are associative.
 
<syntaxhighlight 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)
}</syntaxhighlight>
 
Tcl also provides associative map values (called “dictionaries”) from 8.5 onwards.
<br>
{{works with|Tcl|8.5}}
<syntaxhighlight 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</syntaxhighlight>
 
=={{header|Toka}}==
Toka provides associative arrays via a library.
 
<syntaxhighlight 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 .</syntaxhighlight>
 
=={{header|UNIX Shell}}==
{{works with|ksh}}
<syntaxhighlight lang="bash">typeset -A hash
hash=( [key1]=val1 [key2]=val2 )
hash[key3]=val3
echo "${hash[key3]}"</syntaxhighlight>
 
{{works with|bash}}
assigning values is the same as ksh, but to declare the variable as an associative array:
<syntaxhighlight lang="bash">declare -A hash</syntaxhighlight>
 
=={{header|UnixPipes}}==
A key value file can be considered as an associative array
<syntaxhighlight 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() {
===Using a Hash===
k=$1
for v in $(cat $map | grep "$k$"); do
echo $v
break
done
}
 
function del() {
print $hash{'key1'};
k=$1
temp=$(mktemp)
$hash{'key1'} = 'val1';
mv $map $temp
cat $temp | grep -v "$k$" > $map
@hash{'key1', 'three'} = ('val1', -238.83);
}
 
function dump() {
===Using a HashRef===
echo "-- Dump begin --"
cat $map
echo "-- Dump complete --"
}
 
init
print $hash->{'key1'};
get c
put c cow
$hash->{'key1'} = 'val1';
get c
dump</syntaxhighlight>
@hash->{'key1', 'three'} = ('val1', -238.83);
 
=={{header|Vala}}==
{{libheader|Gee}}
<syntaxhighlight 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"));
}
</syntaxhighlight>
 
Compile with flag: <pre> --pkg gee-1.0 </pre>
 
=={{header|VBA}}==
See '''[https://msdn.microsoft.com/en-us/library/x4k5wbx4.aspx here]''' in the MSDN the reference for the Dictionary object that can be used in VBA. The following example shows how to create a dictionary, add/remove keys, change a key or a value, and check the existence of a key.
 
<syntaxhighlight lang="vb">Option Explicit
Sub Test()
Dim h As Object
Set h = CreateObject("Scripting.Dictionary")
h.Add "A", 1
h.Add "B", 2
h.Add "C", 3
Debug.Print h.Item("A")
h.Item("C") = 4
h.Key("C") = "D"
Debug.Print h.exists("C")
h.Remove "B"
Debug.Print h.Count
h.RemoveAll
Debug.Print h.Count
End Sub</syntaxhighlight>
 
=={{header|Vim Script}}==
Dictionary keys are always strings.
<syntaxhighlight 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</syntaxhighlight>
 
=={{header|Visual FoxPro}}==
Visual FoxPro has a collection class which can be used for this.
<syntaxhighlight 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
</syntaxhighlight>
 
=={{header|V (Vlang)}}==
<syntaxhighlight lang="v (vlang)">fn main() {
// make empty map
mut my_map := map[string]int{}
 
//s et value
my_map['foo'] = 3
 
// getting values
y1 := my_map['foo']
 
// remove keys
my_map.delete('foo')
 
// make map with values
my_map = {
'foo': 2
'bar': 42
'baz': -1
}
}</syntaxhighlight>
 
=={{header|Wart}}==
<syntaxhighlight lang="wart">h <- (table 'a 1 'b 2)
h 'a
=> 1</syntaxhighlight>
 
=={{header|Wren}}==
Wren has a Map class built in.
<syntaxhighlight lang="wren">var fruit = {} // creates an empty map
fruit[1] = "orange" // associates a key of 1 with "orange"
fruit[2] = "apple" // associates a key of 2 with "apple"
System.print(fruit[1]) // retrieves the value with a key of 1 and prints it out
fruit.remove(1) // removes the entry with a key of 1 from the map
System.print(fruit) // prints the rest of the map
System.print()
var capitals = { // creates a new map with three entries
"France": "Paris",
"Germany": "Berlin",
"Spain": "Madrid"
}
capitals["Russia"] = "Moscow" // adds another entry
System.print(capitals["France"]) // retrieves the "France" entry and prints out its capital
capitals.remove("France") // removes the "France" entry
System.print(capitals) // prints all remaining entries
System.print(capitals.count) // prints the number of remaining entries
System.print(capitals["Sweden"]) // prints the entry for Sweden (null as there isn't one)</syntaxhighlight>
 
{{out}}
==[[Python]]==
<pre>
[[Category:Python]]
orange
In Python, hashes are called dictionaries.
{2: apple}
 
Paris
# empty dictionary
{Russia: Moscow, Germany: Berlin, Spain: Madrid}
d = {}
3
d['spam'] = 1
null
d['eggs'] = 2
</pre>
 
=={{header|XLISP}}==
# dictionaries with two keys
XLISP refers to associative arrays as tables. The <tt>MAKE-TABLE</tt> function returns a new empty table, for instance:
d1 = {'spam': 1, 'eggs': 2}
<syntaxhighlight lang="lisp">(define starlings (make-table))</syntaxhighlight>
d2 = dict(spam=1, eggs=2)
Values can then be inserted using <tt>TABLE-SET!</tt>:
<syntaxhighlight lang="lisp">(table-set! starlings "Common starling" "Sturnus vulgaris")
(table-set! starlings "Abbot's starling" "Poeoptera femoralis")
(table-set! starlings "Cape starling" "Lamprotornis nitens")</syntaxhighlight>
and retrieved using <tt>TABLE-REF</tt> with their keys:
<syntaxhighlight lang="lisp">(table-ref starlings "Cape starling")</syntaxhighlight>
Output in a REPL:
<pre>"Lamprotornis nitens"</pre>
Other functions provided for tables include <tt>MAP-OVER-TABLE-ENTRIES</tt>, which takes a table and a function of two arguments and applies the function to each entry (using the key and value as the two arguments), for instance:
<syntaxhighlight lang="lisp">(map-over-table-entries starlings (lambda (x y) (print (string-append x " (Linnaean name " y ")"))))</syntaxhighlight>
Output in a REPL:
<pre>"Abbott's starling (Linnaean name Poeoptera femoralis)"
"Common starling (Linnaean name Sturnus vulgaris)"
"Cape starling (Linnaean name Lamprotornis nitens)"</pre>
 
=={{header|XPL0}}==
# dictionaries from tuple list
<syntaxhighlight lang="xpl0">include c:\cxpl\stdlib;
d1 = dict([('spam', 1), ('eggs', 2)])
char Dict(10,10);
d2 = dict(zip(['spam', 'eggs'], [1, 2]))
int Entries;
 
proc AddEntry(Letter, Greek); \Insert entry into associative array
# iterating over keys
char Letter, Greek;
for key in d:
[Dict(Entries,0):= Letter;
print key, d[key]
StrCopy(Greek, @Dict(Entries,1));
Entries:= Entries+1; \(limit checks ignored for simplicity)
];
 
func Lookup(Greek); \Given Greek name return English letter
# iterating over (key, value) pairs
char Greek;
for key, value in d.iteritems():
int I;
print key, value
[for I:= 0, Entries-1 do
if StrCmp(Greek, @Dict(I,1)) = 0 then return Dict(I,0);
return ^?;
];
 
[Entries:= 0;
Create a generic mapping function that applys a callback to elements in a list:
AddEntry(^A, "alpha");
AddEntry(^D, "delta");
AddEntry(^B, "beta");
AddEntry(^C, "gamma");
ChOut(0, Lookup("beta")); CrLf(0);
ChOut(0, Lookup("omega")); CrLf(0);
]</syntaxhighlight>
 
For greater speed a hashing algorithm should be used to look up items in
==[[Ruby]]==
a large dictionary, however hashing routines are not provided in the
[[Category:Ruby]]
standard library.
A hash object that returns [[nil]] for unknown keys
hash={}
hash[666]='devil'
hash[777] # => nil
hash[666] # => 'devil'
 
{{out}}
A hash object that returns 'unknown key' for unknown keys
<pre>
hash=Hash.new('unknown key')
B
hash[666]='devil'
?
hash[777] # => 'unknown key'
</pre>
hash[666] # => 'devil'
 
=={{header|zkl}}==
A hash object that returns "unknown key #{key}" for unknown keys
<syntaxhighlight lang="zkl">zkl: Dictionary("one",1, "two",2, "three",3)
hash=Hash.new{|h,k|h[k]="unknown key #{k}"}
D(two:2,three:3,one:1)
hash[666]='devil'
hash[777] # => 'unknown key 777'
hash[666] # => 'devil'
 
zkl: T("one",1, "two",2, "three",3).toDictionary()
==[[SmallTalk]]==
D(two:2,three:3,one:1)</syntaxhighlight>
[[Category:SmallTalk]]
 
{{omit from|Applesoft BASIC}}
"Tested with Dolphin Smalltalk"
{{omit from|bc|No associative arrays. No string operations.}}
states := Dictionary new.
{{omit from|Brainf***}}
states at: 'MI' put: 'Michigan'.
{{omit from|dc|No associative arrays. No string operations.}}
states at: 'MN' put: 'Minnesota'.
{{omit from|GUISS}}
{{omit from|Integer BASIC}}
{{omit from|TI-83 BASIC|Same reason as TI-89.}}
{{omit from|TI-89 BASIC|Does not have associative arrays (unless you write a whole library yourself).}}
885

edits