Associative array/Iteration: Difference between revisions
GP |
|||
Line 986: | Line 986: | ||
=={{header|JavaScript}}== |
=={{header|JavaScript}}== |
||
JavaScript does not have associative arrays. |
JavaScript does not have associative arrays until ECMAScript 6 brings Maps. In versions up to ES5.1, you may add properties to an empty object to achieve the same effect. |
||
<lang javascript>var myhash = {}; // |
<lang javascript>var myhash = {}; //a new, empty object |
||
myhash["hello"] = 3; |
myhash["hello"] = 3; |
||
myhash.world = 6; |
myhash.world = 6; //obj.name is equivalent to obj["name"] for certain values of name |
||
myhash["!"] = 9; |
myhash["!"] = 9; |
||
//iterate using for..in loop |
|||
var output = '', // initialise as string |
|||
⚫ | |||
key; |
|||
//ensure key is in object and not in prototype |
|||
⚫ | |||
if (myhash.hasOwnProperty(key)) { |
|||
console.log("Key is: " + key + '. Value is: ' + myhash[key]); |
|||
⚫ | |||
output += " => "; |
|||
} |
|||
output += "value is: " + myhash[key]; // cannot use myhash.key, that would be myhash["key"] |
|||
output += "\n"; |
|||
⚫ | |||
⚫ | |||
//iterate using ES5.1 Object.keys() and Array.prototype.Map() |
|||
To iterate over values in JavaScript 1.6+: |
|||
var keys = Object.keys(); //get Array of object keys (doesn't get prototype keys) |
|||
<lang javascript>var myhash = {}; // a new, empty object |
|||
keys.map(function (key) { |
|||
myhash["hello"] = 3; |
|||
console.log("Key is: " + key + '. Value is: ' + myhash[key]); |
|||
myhash.world = 6; // obj.name is equivalent to obj["name"] for certain values of name |
|||
⚫ | |||
myhash["!"] = 9; |
|||
var output = '', // initialise as string |
|||
val; |
|||
for (val in myhash) { |
|||
if (myhash.hasOwnProperty(val)) { |
|||
output += "myhash['" + val + "'] is: " + myhash[val]; |
|||
output += "\n"; |
|||
} |
|||
}</lang> |
|||
=={{header|Jq}}== |
=={{header|Jq}}== |
Revision as of 15:04, 3 June 2015
You are encouraged to solve this task according to the task description, using any language you may know.
Show how to iterate over the key-value pairs of an associative array, and print each pair out. Also show how to iterate just over the keys, or the values, if there is a separate way to do that in your language.
- See also
- Array
- Associative array: Creation, Iteration
- Collections
- Compound data type
- Doubly-linked list: Definition, Element definition, Element insertion, List Traversal, Element Removal
- Linked list
- Queue: Definition, Usage
- Set
- Singly-linked list: Element definition, Element insertion, List Traversal, Element Removal
- Stack
Ada
<lang Ada>with Ada.Text_IO; use Ada.Text_IO; with Ada.Containers.Indefinite_Ordered_Maps;
procedure Test_Iteration is
package String_Maps is new Ada.Containers.Indefinite_Ordered_Maps (String, Integer); use String_Maps; A : Map; Index : Cursor;
begin
A.Insert ("hello", 1); A.Insert ("world", 2); A.Insert ("!", 3); Index := A.First; while Index /= No_Element loop Put_Line (Key (Index) & Integer'Image (Element (Index))); Index := Next (Index); end loop;
end Test_Iteration;</lang>
- Output:
! 3 hello 1 world 2
Aime
<lang aime>record r; text s;
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
if (r_first(r, s)) {
do { o_form("key ~, value ~ (~)\n", s, r[s], r_type(r, s)); } while (r_greater(r, s, s));
}</lang>
- Output:
key A, value 33 (integer) key B, value associative (text) key C, value 2.5 (real)
App Inventor
Associative arrays in App Inventor are lists of key:value 'pairs'.
When a list is organized as pairs, the lookup in pairs block can be used to retrieve an associated value from a key name.
<VIEW BLOCKS AND ANDROID APP>
AutoHotkey
From the documentation<lang AutoHotkey>; Create an associative array obj := Object("red", 0xFF0000, "blue", 0x0000FF, "green", 0x00FF00) enum := obj._NewEnum() While enum[key, value]
t .= key "=" value "`n"
MsgBox % t</lang>
AWK
In AWK "arrays" are always associative arrays, and the only way to iterate over them is by keys (indexes in the AWK terminology)
<lang awk>BEGIN {
a["hello"] = 1 a["world"] = 2 a["!"] = 3
# iterate over keys for(key in a) { print key, a[key] }
}</lang>
Babel
Use the entsha (mnemonic: "get entries from the hash") operator to obtain a list of all entries, where each entry consists of a 3-element list containing the hashed-key, the key and the value in that order.
<lang babel>((main
{ (('foo' 12) ('bar' 33) ('baz' 42)) mkhash !
entsha dup {1 ith nl <<} each
"-----\n" <<
{2 ith %d nl <<} each})
(mkhash
{ <- newha -> { <- dup -> dup 1 ith <- 0 ith -> inskha } each }))</lang>
This program generates the following
- Output:
foo baz bar ----- 12 42 33
Note that the entsha operator does not return the entries of the hash in any particular order. In general, there is no automatic way to recover the order in which the entries were inserted into the hash.
BASIC256
Solution is at Associative_array/Creation#BASIC256.
BBC BASIC
<lang bbcbasic> REM Store some values with their keys:
PROCputdict(mydict$, "FF0000", "red") PROCputdict(mydict$, "00FF00", "green") PROCputdict(mydict$, "0000FF", "blue") REM Iterate through the dictionary: i% = 1 REPEAT i% = FNdict(mydict$, i%, v$, k$) PRINT v$, k$ UNTIL i% = 0 END DEF PROCputdict(RETURN dict$, value$, key$) IF dict$ = "" dict$ = CHR$(0) dict$ += key$ + CHR$(1) + value$ + CHR$(0) ENDPROC DEF FNdict(dict$, I%, RETURN value$, RETURN key$) LOCAL J%, K% J% = INSTR(dict$, CHR$(1), I%) K% = INSTR(dict$, CHR$(0), J%) value$ = MID$(dict$, I%+1, J%-I%-1) key$ = MID$(dict$, J%+1, K%-J%-1) IF K% >= LEN(dict$) THEN K% = 0 = K%</lang>
Bracmat
<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) & (myhash..remove)$formula & (myhash..insert)$(formula.x^2+y^2) & (myhash..forall)
$ ( = key value . whl ' ( !arg:(?key.?value) ?arg & put$("key:" !key "\nvalue:" !value \n) ) & put$\n )
);</lang>
- Output:
key: meat value: key: title value: Some title key: formula value: x^2+y^2 key: fruit value: melons bananas key: fruit value: apples oranges kiwis
Brat
<lang brat>h = [ hello: 1 world: 2 :! : 3]
- Iterate over key, value pairs
h.each { k, v |
p "Key: #{k} Value: #{v}"
}
- Iterate over keys
h.each_key { k |
p "Key: #{k}"
}
- Iterate over values
h.each_value { v |
p "Value: #{v}"
}</lang>
C
Solution is at Associative arrays/Creation/C.
C++
<lang cpp>#include <iostream>
- include <map>
- include <string>
int main() {
std::map<std::string, int> dict { {"One", 1}, {"Two", 2}, {"Three", 7} };
dict["Three"] = 3;
std::cout << "One: " << dict["One"] << std::endl; std::cout << "Key/Value pairs: " << std::endl; for(auto& kv: dict) { std::cout << " " << kv.first << ": " << kv.second << std::endl; }
return 0;
}</lang>
Pre C++11:
<lang cpp>std::map<std::string, int> myDict;
myDict["hello"] = 1;
myDict["world"] = 2;
myDict["!"] = 3;
// iterating over key-value pairs: for (std::map<std::string, int>::iterator it = myDict.begin(); it != myDict.end(); ++it) {
// the thing pointed to by the iterator is an std::pair<const std::string, int>& const std::string& key = it->first; int& value = it->second; std::cout << "key = " << key << ", value = " << value << std::endl;
}</lang>
C#
<lang csharp>using System; using System.Collections.Generic;
namespace AssocArrays {
class Program { static void Main(string[] args) {
Dictionary<string,int> assocArray = new Dictionary<string,int>();
assocArray["Hello"] = 1; assocArray.Add("World", 2); assocArray["!"] = 3;
foreach (KeyValuePair<string, int> kvp in assocArray) { Console.WriteLine(kvp.Key + " : " + kvp.Value); }
foreach (string key in assocArray.Keys) { Console.WriteLine(key); }
foreach (int val in assocArray.Values) { Console.WriteLine(val.ToString()); } } }
} </lang>
Chapel
<lang chapel>var A = [ "H2O" => "water", "NaCl" => "salt", "O2" => "oxygen" ];
for k in A.domain do
writeln("have key: ", k);
for v in A do
writeln("have value: ", v);
for (k,v) in zip(A.domain, A) do
writeln("have element: ", k, " -> ", v);</lang>
- Output:
have key: O2 have key: NaCl have key: H2O have value: oxygen have value: salt have value: water have element: O2 -> oxygen have element: NaCl -> salt have element: H2O -> water
Clojure
<lang clojure> (doseq [[k v] {:a 1, :b 2, :c 3}]
(println k "=" v))
(doseq [k (keys {:a 1, :b 2, :c 3})]
(println k))
(doseq [v (vals {:a 1, :b 2, :c 3})]
(println v))
</lang>
CoffeeScript
<lang coffeescript>hash =
a: 'one' b: 'two'
for key, value of hash
console.log key, value
for key of hash
console.log key
</lang>
Common Lisp
Common Lisp has three common idioms for associating keys with values: association lists (alists), property lists (plists), and hash tables.
With association lists (alists)
The association list is a list of conses, each of whose car
is a key and whose cdr
is a value. The standard mapping and print functions can be used to print key/value pairs, keys, and values.
<lang lisp>;; iterate using dolist, destructure manually (dolist (pair alist)
(destructuring-bind (key . value) pair (format t "~&Key: ~a, Value: ~a." key value)))
- iterate and destructure with loop
(loop for (key . value) in alist
do (format t "~&Key: ~a, Value: ~a." key value))</lang>
With property lists (plists)
Property lists are lists of alternating keys and values, where each value's key is the element of the list immediately following it. Printing could be done with standard mapping functions, but loop
's destructuring makes things a bit easier.
<lang lisp>(loop for (key value) on plist :by 'cddr
do (format t "~&Key: ~a, Value: ~a." key value))</lang>
With hash tables
Lisp also has built-in hash tables, and there are several ways to map over these. The first is maphash
which takes a function of two arguments (the key and value) and the hash table.
<lang lisp>(maphash (lambda (key value)
(format t "~&Key: ~a, Value: ~a." key value)) hash-table)</lang>
The loop
construct also supports extracting key/value pairs from hash tables.
<lang lisp>(loop for key being each hash-key of hash-table using (hash-value value)
do (format t "~&Key: ~a, Value: ~a." key value))</lang>
There is also a macro with-hash-table-iterator
which locally binds a name to produce associated keys and values of the hash table; while rarely used, it is the most powerful operation.
<lang lisp>(with-hash-table-iterator (next-entry hash-table)
(loop (multiple-value-bind (nextp key value) (next-entry) (if (not nextp) (return) (format t "~&Key: ~a, Value: ~a." key value)))))</lang>
D
<lang d>import std.stdio: writeln;
void main() {
// the associative array auto aa = ["alice":2, "bob":97, "charlie":45];
// how to iterate key/value pairs: foreach (key, value; aa) writeln("1) Got key ", key, " with value ", value); writeln();
// how to iterate the keys: foreach (key, _; aa) writeln("2) Got key ", key); writeln();
// how to iterate the values: foreach (value; aa) writeln("3) Got value ", value); writeln();
// how to extract the values, lazy: foreach (value; aa.byValue()) writeln("4) Got value ", value); writeln();
// how to extract the keys, lazy: foreach (key; aa.byKey()) writeln("5) Got key ", key); writeln();
// how to extract all the keys: foreach (key; aa.keys) writeln("6) Got key ", key); writeln();
// how to extract all the values: foreach (value; aa.values) writeln("7) Got value ", value);
}</lang>
Dao
<lang ruby> dict = { 'def' => 1, 'abc' => 2 }
for( keyvalue in dict ) io.writeln( keyvalue ); for( key in dict.keys(); value in dict.values() ) io.writeln( key, value ) dict.iterate { [key, value]
io.writeln( key, value )
} </lang>
Delphi
<lang Delphi>program AssociativeArrayIteration;
{$APPTYPE CONSOLE}
uses SysUtils, Generics.Collections;
var
i: Integer; s: string; lDictionary: TDictionary<string, Integer>; lPair: TPair<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);
for lPair in lDictionary do Writeln(Format('Pair: %s = %d', [lPair.Key, lPair.Value])); for s in lDictionary.Keys do Writeln('Key: ' + s); for i in lDictionary.Values do Writeln('Value: ', i); finally lDictionary.Free; end;
end.</lang>
E
In E, the basic iteration protocol and syntax work over key-value pairs. Therefore, any iteration over a map or other collection is always key-value, though the user may choose to ignore the keys or the values.
The for
loop takes either one pattern, for the value, or two, for the key and value; for iterating over keys alone the value may be given an ignore-pattern (_
).
<lang e>def map := [
"a" => 1, "b" => 2, "c" => 3,
]
for key => value in map {
println(`$key $value`)
}
for value in map { # ignore keys
println(`. $value`)
}
for key => _ in map { # ignore values
println(`$key .`)
}
for key in map.domain() { # iterate over the set whose values are the keys
println(`$key .`)
}</lang>
Elena
<lang elena>#define system.
- define system'collections.
// --- Program ---
- symbol program =
[
// 1. Create #var aMap := Dictionary new. aMap set &key:"key" &object:"foox". aMap set &key:"key" &object:"foo". aMap set &key:"key2" &object:"foo2". aMap set &key:"key3" &object:"foo3". aMap set &key:"key4" &object:"foo4".
// Enumerate control run:aMap &forEach: aKeyValue [ console write:(aKeyValue key) write:" : " writeLine:aKeyValue ].
].</lang>
Erlang
<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(D) ->
lists:foreach(fun (K) -> io:format("~p: ~b~n",[K,dict:fetch(K,D)]) end, dict:fetch_keys(D)).
</lang>
- Output:
32> assoc:test_create(). bar: 2 foo: 1 ok
F#
Iterating over both. <lang fsharp> let myMap = [ ("Hello", 1); ("World", 2); ("!", 3) ]
for k, v in myMap do
printfn "%s -> %d" k v
</lang>
Iterating over either keys or values only can be achieved through use of the _ wildcard token. <lang fsharp> // Only prints the keys. for k, _ in myMap do
printfn "%s" k
// Only prints the values. for _, v in myMap do
printfn "%d" v
</lang>
Factor
<lang factor>H{ { "hi" "there" } { "a" "b" } } [ ": " glue print ] assoc-each</lang>
There's also assoc-map
, assoc-find
, assoc-filter
and many more.
Fantom
Given a map, each
iterates over pairs of values-keys. keys
and vals
retrieve a list of keys or values, respectively.
<lang fantom> class Main {
public static Void main () { Int:Str map := [1:"alpha", 2:"beta", 3:"gamma"]
map.keys.each |Int key| { echo ("Key is: $key") }
map.vals.each |Str value| { echo ("Value is: $value") }
map.each |Str value, Int key| { echo ("Key $key maps to $value") } }
} </lang>
Forth
<lang forth>include ffl/hct.fs include ffl/hci.fs
\ Create hashtable and iterator in dictionary 10 hct-create htable htable hci-create hiter
\ Insert entries 1 s" hello" htable hct-insert 2 s" world" htable hct-insert 3 s" !" htable hct-insert
- iterate
hiter hci-first BEGIN WHILE ." key = " hiter hci-key type ." , value = " . cr hiter hci-next REPEAT
iterate</lang>
<lang forth> \ Written in ANS-Forth; tested under VFX. \ Requires the novice package: http://www.forth.org/novice.html \ The following should already be done: \ include novice.4th \ include association.4th
\ I would define high-level languages as those that allow programs to be written without explicit iteration. Iteration is a major source of bugs. \ The example from the FFL library doesn't hide iteration, whereas this example from the novice-package does.
marker AssociationIteration.4th
\ ****** \ ****** The following defines a node in an association (each node is derived from ELEMENT). \ ******
element
w field .inventor
constant language \ describes a programming language
- init-language ( inventor name node -- node )
init-element >r hstr r@ .inventor ! r> ;
- new-language ( inventor name -- node )
language alloc init-language ;
- show-language ( count node -- )
>r 1+ \ -- count+1 cr r@ .key @ count colorless type ." invented by: " r@ .inventor @ count type rdrop ;
- show-languages-forward ( handle -- )
0 \ -- handle count swap .root @ ['] show-language walk> cr ." count: " . cr ;
- show-languages-backward ( handle -- )
0 \ -- handle count swap .root @ ['] show-language <walk cr ." count: " . cr ;
- kill-language-attachments ( node -- )
dup .inventor @ dealloc kill-key ;
- copy-language-attachments ( src dst -- )
over .inventor @ hstr over .inventor ! copy-key ;
\ ******
\ ****** The following defines the association itself (the handle).
\ ******
association constant languages \ describes a set of programming languages
- init-languages ( record -- record )
>r ['] compare ['] kill-language-attachments ['] copy-language-attachments r> init-association ;
- new-languages ( -- record )
languages alloc init-languages ;
\ ******
\ ****** The following filters one association into another, including everything that matches a particular inventor.
\ ******
- <filter-inventor> { inventor handle new-handle node -- inventor handle new-handle }
inventor count node .inventor @ count compare A=B = if node handle dup-element new-handle insert then inventor handle new-handle ;
- filter-inventor ( inventor handle -- new-handle )
dup similar-association \ -- inventor handle new-handle over .root @ ['] <filter-inventor> walk> \ -- inventor handle new-handle nip nip ;
\ ****** \ ****** The following is a demonstration with some sample data. \ ******
new-languages
c" Moore, Chuck" c" Forth " new-language over insert c" Ichiah, Jean" c" Ada " new-language over insert c" Wirth, Niklaus" c" Pascal " new-language over insert c" Wirth, Niklaus" c" Oberon " new-language over insert c" McCarthy, John" c" Lisp " new-language over insert c" van Rossum, Guido" c" Python " new-language over insert c" Gosling, Jim" c" Java " new-language over insert c" Ierusalimschy, Roberto" c" Lua " new-language over insert c" Matsumoto, Yukihiro" c" Ruby " new-language over insert c" Pestov, Slava" c" Factor " new-language over insert c" Gosling, James" c" Java " new-language over insert c" Wirth, Niklaus" c" Modula-2 " new-language over insert c" Ritchie, Dennis" c" C " new-language over insert c" Stroustrup, Bjarne" c" C++ " new-language over insert
constant some-languages
cr .( everything in SOME-LANGUAGES ordered forward: )
some-languages show-languages-forward
cr .( everything in SOME-LANGUAGES ordered backward: )
some-languages show-languages-backward
cr .( everything in SOME-LANGUAGES invented by Wirth: )
c" Wirth, Niklaus" some-languages filter-inventor dup show-languages-forward kill-association
cr .( everything in SOME-LANGUAGES within 'F' and 'L': )
c" F" c" L" some-languages filter within dup show-languages-forward kill-association
cr .( everything in SOME-LANGUAGES not within 'F' and 'L': )
c" F" c" L" some-languages filter without dup show-languages-forward kill-association
some-languages kill-association
</lang>
- Output:
everything in SOME-LANGUAGES ordered forward: Ada invented by: Ichiah, Jean C invented by: Ritchie, Dennis C++ invented by: Stroustrup, Bjarne Factor invented by: Pestov, Slava Forth invented by: Moore, Chuck Java invented by: Gosling, James Lisp invented by: McCarthy, John Lua invented by: Ierusalimschy, Roberto Modula-2 invented by: Wirth, Niklaus Oberon invented by: Wirth, Niklaus Pascal invented by: Wirth, Niklaus Python invented by: van Rossum, Guido Ruby invented by: Matsumoto, Yukihiro count: 13 everything in SOME-LANGUAGES ordered backward: Ruby invented by: Matsumoto, Yukihiro Python invented by: van Rossum, Guido Pascal invented by: Wirth, Niklaus Oberon invented by: Wirth, Niklaus Modula-2 invented by: Wirth, Niklaus Lua invented by: Ierusalimschy, Roberto Lisp invented by: McCarthy, John Java invented by: Gosling, James Forth invented by: Moore, Chuck Factor invented by: Pestov, Slava C++ invented by: Stroustrup, Bjarne C invented by: Ritchie, Dennis Ada invented by: Ichiah, Jean count: 13 everything in SOME-LANGUAGES invented by Wirth: Modula-2 invented by: Wirth, Niklaus Oberon invented by: Wirth, Niklaus Pascal invented by: Wirth, Niklaus count: 3 everything in SOME-LANGUAGES within 'F' and 'L': Factor invented by: Pestov, Slava Forth invented by: Moore, Chuck Java invented by: Gosling, James count: 3 everything in SOME-LANGUAGES not within 'F' and 'L': Ada invented by: Ichiah, Jean C invented by: Ritchie, Dennis C++ invented by: Stroustrup, Bjarne Lisp invented by: McCarthy, John Lua invented by: Ierusalimschy, Roberto Modula-2 invented by: Wirth, Niklaus Oberon invented by: Wirth, Niklaus Pascal invented by: Wirth, Niklaus Python invented by: van Rossum, Guido Ruby invented by: Matsumoto, Yukihiro count: 10
Go
<lang go>myMap := map[string]int { "hello": 13, "world": 31, "!" : 71 }
// iterating over key-value pairs: for key, value := range myMap {
fmt.Printf("key = %s, value = %d\n", key, value)
}
// iterating over keys: for key := range myMap {
fmt.Printf("key = %s\n", key)
}
// iterating over values: for _, value := range myMap {
fmt.Printf("value = %d\n", value)
}</lang>
Groovy
Solution: <lang groovy>def map = [lastName: "Anderson", firstName: "Thomas", nickname: "Neo", age: 24, address: "everywhere"]
println "Entries:" map.each { println it }
println() println "Keys:" map.keySet().each { println it }
println() println "Values:" map.values().each { println it }</lang>
- Output:
Entries: lastName=Anderson firstName=Thomas nickname=Neo age=24 address=everywhere Keys: lastName firstName nickname age address Values: Anderson Thomas Neo 24 everywhere
Harbour
<lang visualfoxpro>LOCAL arr := { 6 => 16, "eight" => 8, "eleven" => 11 } LOCAL x
FOR EACH x IN arr
// key, value ? x:__enumKey(), x // or key only ? x:__enumKey() // or value only ? x
NEXT</lang>
Haskell
with Data.Map: <lang haskell>import qualified Data.Map as M
myMap = M.fromList [("hello", 13), ("world", 31), ("!", 71)]
main = do -- pairs
print $ M.toList myMap -- keys print $ M.keys myMap -- values print $ M.elems myMap</lang>
Icon and Unicon
<lang icon>procedure main()
t := table() every t[a := !"ABCDE"] := map(a)
every pair := !sort(t) do write("\t",pair[1]," -> ",pair[2])
writes("Keys:") every writes(" ",key(t)) write()
writes("Values:") every writes(" ",!t) write()
end</lang>
- Output:
->aai A -> a B -> b C -> c D -> d E -> e Keys: C E B D A Values: c e b d a
J
Note that all J operations either iterate over the items of an array or can be made to do so. So to iterate over some sequence you need to refer to that sequence.
Using the J example from Creating an Associative Array...
Keys <lang J>nl__example 0</lang>
Values <lang J>get__example each nl__example 0</lang>
Both keys and values <lang J>(,&< get__example) each nl__example 0</lang>
Note that this last is not likely to be useful in any practical context outside of learning the language.
Java
<lang java>Map<String, Integer> myDict = new HashMap<String, Integer>(); myDict.put("hello", 1); myDict.put("world", 2); myDict.put("!", 3);
// iterating over key-value pairs: for (Map.Entry<String, Integer> e : myDict.entrySet()) {
String key = e.getKey(); Integer value = e.getValue(); System.out.println("key = " + key + ", value = " + value);
}
// iterating over keys: for (String key : myDict.keySet()) {
System.out.println("key = " + key);
}
// iterating over values: for (Integer value : myDict.values()) {
System.out.println("value = " + value);
}</lang>
Java 8 version
<lang java>Map<String, Integer> myDict = new HashMap<>(); myDict.put("hello", 1); myDict.put("world", 2); myDict.put("!", 3);
// iterating over key-value pairs: myDict.forEach((k, v) -> {
System.out.printf("key = %s, value = %s%n", k, v);
});
// iterating over keys: myDict.keySet().forEach(k -> System.out.printf("key = %s%n", k));
// iterating over values: myDict.values().forEach(v -> System.out.printf("value = %s%n", v));</lang>
key = !, value = 3 key = world, value = 2 key = hello, value = 1 key = ! key = world key = hello value = 3 value = 2 value = 1
JavaScript
JavaScript does not have associative arrays until ECMAScript 6 brings Maps. In versions up to ES5.1, you may add properties to an empty object to achieve the same effect. <lang javascript>var myhash = {}; //a new, empty object myhash["hello"] = 3; myhash.world = 6; //obj.name is equivalent to obj["name"] for certain values of name myhash["!"] = 9;
//iterate using for..in loop for (var key in myhash) {
//ensure key is in object and not in prototype if (myhash.hasOwnProperty(key)) { console.log("Key is: " + key + '. Value is: ' + myhash[key]); }
}
//iterate using ES5.1 Object.keys() and Array.prototype.Map() var keys = Object.keys(); //get Array of object keys (doesn't get prototype keys) keys.map(function (key) {
console.log("Key is: " + key + '. Value is: ' + myhash[key]);
});</lang>
Jq
In jq, there are several ways to iterate over compound structures:
- functionally, e.g. using map on an array - by enumeration, i.e. by generating a stream - by performing a reduction
For the sake of brevity, therefore, in the following we will only illustrate the enumerative approach.
With respect to associative arrays (i.e. JSON objects), the fundamental functions are:
- keys -- for producing an array of the keys (sorted) - .[] -- for producing a stream of the values
In jq > 1.4, keys_unsorted, for producing an array of the keys (in the order of creation), is also available. <lang jq>def mydict: {"hello":13, "world": 31, "!": 71};
- Iterating over the keys
mydict | keys[]
- "!"
- "hello"
- "world"
- Iterating over the values:
mydict[]
- 13
- 31
- 71
- Generating a stream of {"key": key, "value": value} objects:
mydict | to_entries[]
- {"key":"hello","value":13}
- {"key":"world","value":31}
- {"key":"!","value":71}
- Generating a stream of [key,value] arrays:
mydict | . as $o | keys[] | [., $o[.]]
- ["!",71]
- ["hello",13]
- ["world",31]
- Generating a stream of [key,value] arrays, without sorting (jq > 1.4 required)
mydict | . as $o | keys_unsorted[] | [., $o[.]]
- ["hello",13]
- ["world",31]
- ["!",71]
</lang>
Julia
<lang julia>mydict = [ "hello"=>13, "world"=>31, "!"=>71 ]
- applying a function to key-value pairs:
map(println, mydict);
- iterating over key-value pairs:
for (key,value) in mydict
println("key = $key, value = $value")
end
- iterating over keys:
for key in keys(mydict)
println("key = $key")
end
- iterating over values:
for value in values(mydict)
println("value = $value")
end</lang>
- Output:
key = !, value = 71 key = hello, value = 13 key = world, value = 31 key = ! key = hello key = world value = 71 value = 13 value = 31
K
Creating a dictionary. <lang K> d: .((`"hello";1); (`"world";2);(`"!";3))</lang>
The keys are available via "!". <lang K> !d `hello `world `"!"
$!d / convert keys (symbols) as strings
("hello"
"world" ,"!")</lang>
Print the key value pairs. <lang K> `0:{,/$x,": ",d[x]}'!d hello: 1 world: 2 !: 3</lang>
The values are available via "[]". <lang K> d[] 1 2 3
{x+1}'d[]
2 3 4</lang>
Lang5
<lang lang5>: first 0 extract nip ; : second 1 extract nip ; : nip swap drop ;
- say(*) dup first " => " 2 compress "" join . second . ;
[['foo 5] ['bar 10] ['baz 20]] 'say apply drop</lang>
Lasso
<lang Lasso> //iterate over associative array //Lasso maps local('aMap' = map('weight' = 112, 'height' = 45, 'name' = 'jason')) ' Map output: \n ' #aMap->forEachPair => {^ //display pair, then show accessing key and value individually #1+'\n ' #1->first+': '+#1->second+'\n ' ^} //display keys and values separately '\n' ' Map Keys: '+#aMap->keys->join(',')+'\n' ' Map values: '+#aMap->values->join(',')+'\n'
//display using forEach '\n' ' Use ForEach to iterate Map keys: \n' #aMap->keys->forEach => {^ #1+'\n' ^} '\n' ' Use ForEach to iterate Map values: \n' #aMap->values->forEach => {^ #1+'\n' ^} //the {^ ^} indicates that output should be printed (AutoCollect) , // if output is not desired, just { } is used </lang>
LFE
Keys and Values
<lang lisp> (let ((data '(#(key1 "foo") #(key2 "bar")))
(hash (: dict from_list data))) (: dict fold (lambda (key val accum) (: io format '"~s: ~s~n" (list key val))) 0 hash))
</lang>
Just Keys
<lang lisp> (let ((data '(#(key1 "foo") #(key2 "bar")))
(hash (: dict from_list data))) (: lists map (lambda (key) (: io format '"~s~n" (list key))) (: dict fetch_keys hash)))
</lang>
Liberty BASIC
Needs the sublist library from http://basic.wikispaces.com/SubList+Library since LB does not have built-in associative arrays. <lang lb> data "red", "255 50 50", "green", "50 255 50", "blue", "50 50 255" data "my fave", "220 120 120", "black", "0 0 0"
myAssocList$ =""
for i =1 to 5
read k$ read dat$ call sl.Set myAssocList$, k$, dat$
next i
keys$ = "" ' List to hold the keys in myList$. keys = 0
keys = sl.Keys( myAssocList$, keys$) print " Number of key-data pairs ="; keys
For i = 1 To keys
keyName$ = sl.Get$( keys$, Str$( i)) Print " Key "; i; ":", keyName$, "Data: ", sl.Get$( myAssocList$, keyName$)
Next i
end </lang>
Number of key-data pairs =5 Key 1: red Data: 255 50 50 Key 2: green Data: 50 255 50 Key 3: blue Data: 50 50 255 Key 4: my fave Data: 220 120 120 Key 5: black Data: 0 0 0
Lua
<lang lua>local t = {
["foo"] = "bar", ["baz"] = 6, fortytwo = 7
}
for key,val in pairs(t) do
print(string.format("%s: %s", key, val))
end</lang>
- Output:
fortytwo: 7 foo: bar baz: 6
Note: the order in which pairs
iterates over non-integer keys is not defined, so the order of lines in the output of the above code may differ from one run to another.
M4
<lang M4>divert(-1) define(`for',
`ifelse($#,0,``$0, `ifelse(eval($2<=$3),1, `pushdef(`$1',$2)$4`'popdef(`$1')$0(`$1',incr($2),$3,`$4')')')')
define(`new',`define(`$1[size]key',0)') define(`asize',`defn(`$1[size]key')') define(`aget',`defn(`$1[$2]')') define(`akget',`defn(`$1[$2]key')') define(`avget',`aget($1,akget($1,$2))') define(`aset',
`ifdef($1[$2], `', `define(`$1[size]key',incr(asize(`$1')))`'define($1[asize(`$1')]key,$2)')`'define($1[$2],$3)')
define(`dquote', ``$@) define(`akeyvalue',`dquote(akget($1,$2),aget($1,akget($1,$2)))') define(`akey',`dquote(akget($1,$2))') define(`avalue',`dquote(aget($1,akget($1,$2)))') divert new(`a') aset(`a',`wow',5) aset(`a',`wow',flame) aset(`a',`bow',7) key-value pairs for(`x',1,asize(`a'),
`akeyvalue(`a',x)
') keys for(`x',1,asize(`a'),
`akey(`a',x)
') values for(`x',1,asize(`a'),
`avalue(`a',x)
')</lang>
- Output:
key-value pairs `wow',`flame' `bow',`7' keys `wow' `bow' values `flame' `7'
Maple
Iterate through indices when indices are all simple expressions: <lang Maple> > T := table( [ "A" = 1, "B" = 2, "C" = 3, "D" = 4 ] ); > for i in indices( T, nolist ) do print(i ) end:
"A"
"B"
"C"
"D"
</lang>
Iterate through indices when indices may be expression sequences: <lang Maple> > T := table( [ "a" = 1, "b" = 2, ("c","d") = 3 ] ): > for i in indices( T ) do print( i, T[ op( i ) ] ) end:
["a"], 1
["b"], 2
["c", "d"], 3
</lang>
Return all index / entry pairs as equations: <lang Maple> > for i in indices( T, pairs ) do print( i) end:
"a" = 1
"b" = 2
("c", "d") = 3
</lang>
<lang Maple> > for i in entries( T ) do print( i) end:
[1]
[3]
[2]
</lang>
Mathematica
<lang Mathematica>keys=DownValues[#,Sort->False]All,1,1,1&; hashes=#/@keys[#]&;
a[2]="string";a["sometext"]=23; keys[a] ->{2,sometext} hashes[a] ->{string,23}</lang>
MATLAB / Octave
Associative arrays can be defined as structs in Matlab and Octave.
<lang Matlab> keys = fieldnames(hash);
for k=1:length(keys), key = keys{k};
value = getfield(hash,key); % get value of key hash = setfield(hash,key,-value); % set value of key
end; </lang>
or
<lang Matlab> keys = fieldnames(hash);
for k=1:length(keys), key = keys{k}; value = hash.(key); % get value of key hash.(key) = -value; % set value of key end; </lang>
Maxima
<lang Maxima>h[1]: 6$ h[9]: 2$
/* iterate over values */ for val in listarray(h) do (
print(val))$
/* iterate over the keys */ for key in rest(arrayinfo(h), 2) do (
val: arrayapply(h, key), print(key, val))$</lang>
NetRexx
<lang NetRexx>/* NetRexx */ options replace format comments java crossref savelog symbols
surname = 'Unknown' -- default value surname['Fred'] = 'Bloggs' surname['Davy'] = 'Jones'
try = 'Fred' say surname[try] surname['Bert']
-- extract the keys loop fn over surname
say fn.right(10) ':' surname[fn] end fn
</lang>
NewLISP
<lang NewLISP>;; using an association list: (setq alist '(("A" "a") ("B" "b") ("C" "c")))
- list keys
(map first alist)
- list values
(map last alist)
- loop over the assocation list
(dolist (elem alist)
(println (format "%s -> %s" (first elem) (last elem))))</lang>
Nim
<lang nim> import tables
var t: TTable[int,string] = initTable[int,string]()
t[1] = "one" t[2] = "two" t[3] = "three" t.add(4,"four")
echo "t has " & $t.len & " elements"
echo "has t key 4? " & $t.hasKey(4) echo "has t key 5? " & $t.hasKey(5)
- iterate keys
echo "key iteration:" for k in t.keys:
echo "at[" & $k & "]=" & t[k]
- itetate pairs
echo "pair iteration:" for k,v in t.pairs:
echo "at[" & $k & "]=" & v
</lang>
- Output:
t has 4 elements has t key 4? true has t key 5? false key iteration: at[1]=one at[2]=two at[3]=three at[4]=four pair iteration: at[1]=one at[2]=two at[3]=three at[4]=four
Oberon-2
<lang oberon2> MODULE AssociativeArray; IMPORT
ADT:Dictionary, Object:Boxed, Out;
TYPE
Key = STRING; Value = Boxed.LongInt;
VAR
assocArray: Dictionary.Dictionary(Key,Value); iterK: Dictionary.IterKeys(Key,Value); iterV: Dictionary.IterValues(Key,Value); aux: Value; k: Key;
BEGIN
assocArray := NEW(Dictionary.Dictionary(Key,Value)); assocArray.Set("ten",NEW(Value,10)); assocArray.Set("eleven",NEW(Value,11)); aux := assocArray.Get("ten"); Out.LongInt(aux.value,0);Out.Ln; aux := assocArray.Get("eleven"); Out.LongInt(aux.value,0);Out.Ln;Out.Ln; (* Iterate keys *) iterK := assocArray.IterKeys(); WHILE (iterK.Next(k)) DO Out.Object(k);Out.Ln END; Out.Ln; (* Iterate values *) iterV := assocArray.IterValues(); WHILE (iterV.Next(aux)) DO Out.LongInt(aux.value,0);Out.Ln END
END AssociativeArray. </lang>
Objeck
<lang objeck> class Iteration {
function : Main(args : String[]) ~ Nil { assoc_array := Collection.StringMap->New(); assoc_array->Insert("Hello", IntHolder->New(1)); assoc_array->Insert("World", IntHolder->New(2)); assoc_array->Insert("!", IntHolder->New(3));
keys := assoc_array->GetKeys(); values := assoc_array->GetValues();
each(i : keys) { key := keys->Get(i)->As(String); value := assoc_array->Find(key)->As(IntHolder)->Get(); "key={$key}, value={$value}"->PrintLine(); };
"-------------"->PrintLine();
each(i : keys) { key := keys->Get(i)->As(String); value := values->Get(i)->As(IntHolder)->Get(); "key={$key}, value={$value}"->PrintLine(); }; }
} </lang>
Objective-C
<lang objc>NSDictionary *myDict = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:13], @"hello", [NSNumber numberWithInt:31], @"world", [NSNumber numberWithInt:71], @"!", nil];
// iterating over keys: for (id key in myDict) {
NSLog(@"key = %@", key);
}
// iterating over values: for (id value in [myDict objectEnumerator]) {
NSLog(@"value = %@", value);
}</lang>
<lang objc>NSDictionary *myDict = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:13], @"hello", [NSNumber numberWithInt:31], @"world", [NSNumber numberWithInt:71], @"!", nil];
// iterating over keys: NSEnumerator *enm = [myDict keyEnumerator]; id key; while ((key = [enm nextObject])) {
NSLog(@"key = %@", key);
}
// iterating over values: enm = [myDict objectEnumerator]; id value; while ((value = [enm nextObject])) {
NSLog(@"value = %@", value);
}</lang>
<lang objc>NSDictionary *myDict = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:13], @"hello", [NSNumber numberWithInt:31], @"world", [NSNumber numberWithInt:71], @"!", nil];
// iterating over keys and values: [myDict enumerateKeysAndObjectsUsingBlock: ^(id key, id value, BOOL *stop) {
NSLog(@"key = %@, value = %@", key, value);
}];</lang>
OCaml
Association array: <lang ocaml>#!/usr/bin/env ocaml
let map = [| ('A', 1); ('B', 2); ('C', 3) |] ;;
(* iterate over pairs *) Array.iter (fun (k,v) -> Printf.printf "key: %c - value: %d\n" k v) map ;;
(* iterate over keys *) Array.iter (fun (k,_) -> Printf.printf "key: %c\n" k) map ;;
(* iterate over values *) Array.iter (fun (_,v) -> Printf.printf "value: %d\n" v) map ;;
(* in functional programming it is often more useful to fold over the elements *) Array.fold_left (fun acc (k,v) -> acc ^ Printf.sprintf "key: %c - value: %d\n" k v) "Elements:\n" map ;;</lang>
Hash table: <lang ocaml>let map = Hashtbl.create 42;; Hashtbl.add map 'A' 1;; Hashtbl.add map 'B' 2;; Hashtbl.add map 'C' 3;;
(* iterate over pairs *) Hashtbl.iter (fun k v -> Printf.printf "key: %c - value: %d\n" k v) map ;;
(* in functional programming it is often more useful to fold over the elements *) Hashtbl.fold (fun k v acc -> acc ^ Printf.sprintf "key: %c - value: %d\n" k v) map "Elements:\n" ;;</lang>
Functional binary search tree: <lang ocaml>module CharMap = Map.Make (Char);; let map = CharMap.empty;; let map = CharMap.add 'A' 1 map;; let map = CharMap.add 'B' 2 map;; let map = CharMap.add 'C' 3 map;;
(* iterate over pairs *) CharMap.iter (fun k v -> Printf.printf "key: %c - value: %d\n" k v) map ;;
(* in functional programming it is often more useful to fold over the elements *) CharMap.fold (fun k v acc -> acc ^ Printf.sprintf "key: %c - value: %d\n" k v) map "Elements:\n" ;;</lang>
ooRexx
<lang oorexx> d = .directory~new d["hello"] = 1 d["world"] = 2 d["!"] = 3
-- iterating over keys: loop key over d
say "key =" key
end
-- iterating over values: loop value over d~allitems
say "value =" value
end
-- iterating over key-value pairs: s = d~supplier loop while s~available
say "key =" s~index", value =" s~item s~next
end </lang>
Oz
<lang oz>declare
MyMap = unit('hello':13 'world':31 '!':71)
in
{ForAll {Record.toListInd MyMap} Show} %% pairs {ForAll {Record.arity MyMap} Show} %% keys {ForAll {Record.toList MyMap} Show} %% values</lang>
PARI/GP
The keys can be retried from a map with Vec: <lang parigp>keys = Vec(M);</lang> You can iterate over the values as usual: <lang parigp>for(i=1,#keys,
print(keys[i]," ",mapget(M,keys[i]))
)</lang>
Perl
<lang perl>#! /usr/bin/perl use strict;
my %pairs = ( "hello" => 13, "world" => 31, "!" => 71 );
- iterate over pairs
- Be careful when using each(), however, because it uses a global iterator
- associated with the hash. If you call keys() or values() on the hash in the
- middle of the loop, the each() iterator will be reset to the beginning. If
- you call each() on the hash somewhere in the middle of the loop, it will
- skip over elements for the "outer" each(). Only use each() if you are sure
- that the code inside the loop will not call keys(), values(), or each().
while ( my ($k, $v) = each %pairs) {
print "(k,v) = ($k, $v)\n";
}
- iterate over keys
foreach my $key ( keys %pairs ) {
print "key = $key, value = $pairs{$key}\n";
}
- or (see note about each() above)
while ( my $key = each %pairs) {
print "key = $key, value = $pairs{$key}\n";
}
- iterate over values
foreach my $val ( values %pairs ) {
print "value = $val\n";
}</lang>
Perl 6
<lang perl6>my %pairs = hello => 13, world => 31, '!' => 71;
for %pairs.kv -> $k, $v {
say "(k,v) = ($k, $v)";
}
{ say "$^a => $^b" } for %pairs.kv;
say "key = $_" for %pairs.keys;
say "value = $_" for %pairs.values;</lang>
PHP
<lang php><?php $pairs = array( "hello" => 1, "world" => 2, "!" => 3 );
// iterate over key-value pairs foreach($pairs as $k => $v) {
echo "(k,v) = ($k, $v)\n";
}
// iterate over keys foreach(array_keys($pairs) as $key) {
echo "key = $key, value = $pairs[$key]\n";
}
// iterate over values foreach($pairs as $value) {
echo "values = $value\n";
} ?></lang>
PicoLisp
Using properties
<lang PicoLisp>(put 'A 'foo 5) (put 'A 'bar 10) (put 'A 'baz 15)
- (getl 'A) # Get the whole property list
-> ((15 . baz) (10 . bar) (5 . foo))
- (mapcar cdr (getl 'A)) # Get all keys
-> (baz bar foo)
- (mapcar car (getl 'A)) # Get all values
-> (15 10 5)</lang>
Using an index tree
<lang PicoLisp>(idx 'A (def "foo" 5) T) (idx 'A (def "bar" 10) T) (idx 'A (def "baz" 15) T)
- A # Get the whole tree
-> ("foo" ("bar" NIL "baz"))
- (idx 'A) # Get all keys
-> ("bar" "baz" "foo")
- (mapcar val (idx 'A)) # Get all values
-> (10 15 5)</lang>
Pike
note that the order is not alphabetic but depends on the hash value of the keys. the order is deterministic however.
<lang Pike> mapping(string:string) m = ([ "A":"a", "B":"b", "C":"c" ]); foreach(m; string key; string value) {
write(key+value);
} Result: BbAaCc
// only keys foreach(m; string key;) {
write(key);
} Result: BAC
// only values foreach(m;; string value) {
write(value);
} Result: bac
</lang>
PostScript
<lang postscript> % over keys and values <</a 1 /b 2 /c 3>> {= =} forall % just keys <</a 1 /b 2 /c 3>> {= } forall % just values <</a 1 /b 2 /c 3>> {pop =} forall </lang>
PowerShell
Using the following hash table:
<lang powershell>$h = @{ 'a' = 1; 'b' = 2; 'c' = 3 }</lang>
Iterating over the key/value pairs is slightly cumbersome as it requires an explicit call to GetEnumerator
:
<lang powershell>$h.GetEnumerator() | ForEach-Object { Write-Host Key: $_.Name, Value: $_.Value }</lang>
A foreach
statement can also be used:
<lang powershell>foreach ($e in $h.GetEnumerator()) {
Write-Host Key: $e.Name, Value: $e.Value
}</lang> Iterating over the keys: <lang powershell>$h.Keys | ForEach-Object { Write-Host Key: $_ }
foreach ($k in $h.Keys) {
Write-Host Key: $k
}</lang> Iterating over the values: <lang powershell>$h.Values | ForEach-Object { Write-Host Value: $_ }
foreach ($v in $h.Values) {
Write-Host Value: $v
}</lang>
Prolog
Following the example at Associative Array Creation (with the understanding that using a predicate to store a hash does not prevent a "key" from having more than one value):
<lang prolog> assert( mymap(key1,value1) ). assert( mymap(key2,value1) ). </lang>
To perform the specific task at hand: <lang prolog> ?- forall( mymap(Key,Value), writeln( [Key,Value]) ).
[key1,value1] [key2,value1] </lang>
In Prolog, however, iteration is "built-in". For example: <lang prolog> ?- mymap(key1, Y). Y = value1.
?- mymap(X, value1). X = key1 ; X = key2. </lang>
To construct the list of keys: <lang prolog> ?- findall( X, mymap(X,value1), Xs). Xs = [key1, key2]. </lang>
To construct the list of distinct values: <lang prolog> ?- findall( Y, mymap(key1,Y), Ys). Ys = [value1]. </lang>
PureBasic
Hashes are a built-in type called Map in Purebasic.
<lang purebasic>NewMap dict.s() dict("de") = "German" dict("en") = "English" dict("fr") = "French"
ForEach dict()
Debug MapKey(dict()) + ":" + dict()
Next</lang>
Python
<lang python>myDict = { "hello": 13, "world": 31, "!" : 71 }
- iterating over key-value pairs:
for key, value in myDict.items():
print ("key = %s, value = %s" % (key, value))
- iterating over keys:
for key in myDict:
print ("key = %s" % key)
- (is a shortcut for:)
for key in myDict.keys():
print ("key = %s" % key)
- iterating over values:
for value in myDict.values():
print ("value = %s" % value)</lang>
R
R lacks a native representation of key-value pairs, but different structures allow named elements, which provide similar functionality.
environment example
<lang r>> env <- new.env() > env"x" <- 123 > env"x"</lang>
[1] 123
<lang r>> index <- "1" > envindex <- "rainfed hay" > for (name in ls(env)) { + cat(sprintf('index=%s, value=%s\n', name, envname)) + }</lang>
index=1, value=rainfed hay index=x, value=123
vector example
<lang r>> x <- c(hello=1, world=2, "!"=3) > print(x["!"])</lang>
! 3
<lang r>> print(unname(x["!"]))</lang>
[1] 3
list example
<lang R>> a <- list(a=1, b=2, c=3.14, d="xyz") > print(a$a)</lang>
[1] 1
<lang R>> print(a$d)</lang>
[1] "xyz"
Racket
Using the dictionary interface, different data structures can be treated as an associative array in Racket.
<lang racket>
- lang racket
(define dict1 #hash((apple . 5) (orange . 10))) ; hash table (define dict2 '((apple . 5) (orange . 10))) ; a-list (define dict3 (vector "a" "b" "c")) ; vector (integer keys)
(dict-keys dict1) ; => '(orange apple) (dict-values dict2) ; => '(5 10) (for/list ([(k v) (in-dict dict3)]) ; => '("0 -> a" "1 -> b" "2 -> c")
(format "~a -> ~a" k v))
</lang>
REXX
<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). │ └────────────────────────────────────────────────────────────────────┘*/
stateF.=' [not defined yet] ' /*sets any/all state former caps.*/ 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, ···).│ └────────────────────────────────────────────────────────────────────┘*/
stateL= /*list of states (empty now). It's nice to be in alpha-*/
/*betic order; they'll be listed in this order. With a */ /*little more code, they could be sorted quite easily. */
call setSC 'al', "Alabama" ,'Tuscaloosa' call setSC 'ca', "California" ,'Benicia' call setSC 'co', "Colorado" ,'Denver City' call setSC 'ct', "Connecticut" ,'Hartford and New Haven (joint)' call setSC 'de', "Delaware" ,'New-Castle' call setSC 'ga', "Georgia" ,'Milledgeville' call setSC 'il', "Illinois" ,'Vandalia' call setSC 'in', "Indiana" ,'Corydon' call setSC 'ia', "Iowa" ,'Iowa City' call setSC 'la', "Louisiana" ,'New Orleans' call setSC 'me', "Maine" ,'Portland' call setSC 'mi', "Michigan" ,'Detroit' call setSC 'ms', "Mississippi" ,'Natchez' call setSC 'mo', "Missoura" ,'Saint Charles' call setSC 'mt', "Montana" ,'Virginia City' call setSC 'ne', "Nebraska" ,'Lancaster' call setSC 'nh', "New Hampshire" ,'Exeter' call setSC 'ny', "New York" ,'New York' call setSC 'nc', "North Carolina" ,'Fayetteville' call setSC 'oh', "Ohio" ,'Chillicothe' call setSC 'ok', "Oklahoma" ,'Guthrie' call setSC 'pa', "Pennsylvania" ,'Lancaster' call setSC 'sc', "South Carolina" ,'Charlestown' call setSC 'tn', "Tennessee" ,'Murfreesboro' call setSC 'vt', "Vermont" ,'Windsor'
do j=1 for words(stateL) /*show all capitals that were set*/ q=word(stateL,j) /*get the next state in the list.*/ say 'the former capital of ('q") " stateN.q " was " stateC.q end /*j*/ /* [↑] display states defined. */
exit /*stick a fork in it, we're done.*/ /*─────────────────────────────────────setSC subroutine─────────────────*/ setSC: arg code; parse arg ,name,cap /*get upper code, get name & cap.*/ stateL=stateL code /*keep a list of all state codes.*/ stateN.code=name /*set the state's name. */ stateC.code=cap /*set the state's capital. */ return /*return to invoker, SET is done.*/</lang>
- Output:
the former capital of (AL) Alabama was Tuscaloosa the former capital of (CA) California was Benicia the former capital of (CO) Colorado was Denver City the former capital of (CT) Connecticut was Hartford and New Haven (joint) the former capital of (DE) Delaware was New-Castle the former capital of (GA) Georgia was Milledgeville the former capital of (IL) Illinois was Vandalia the former capital of (IN) Indiana was Corydon the former capital of (IA) Iowa was Iowa City the former capital of (LA) Louisiana was New Orleans the former capital of (ME) Maine was Portland the former capital of (MI) Michigan was Detroit the former capital of (MS) Mississippi was Natchez the former capital of (MO) Missoura was Saint Charles the former capital of (MT) Montana was Virginia City the former capital of (NE) Nebraska was Lancaster the former capital of (NH) New Hampshire was Exeter the former capital of (NY) New York was New York the former capital of (NC) North Carolina was Fayetteville the former capital of (OH) Ohio was Chillicothe the former capital of (OK) Oklahoma was Guthrie the former capital of (PA) Pennsylvania was Lancaster the former capital of (SC) South Carolina was Charlestown the former capital of (TN) Tennessee was Murfreesboro the former capital of (VT) Vermont was Windsor
When this example was started, the intention was to list the former capitals by key. Unfortunately, there's a duplicate (Lancaster).
RLaB
Associative arrays are called lists in RLaB.
<lang RLaB> x = <<>>; // create an empty list x.hello = 1; x.world = 2; x.["!"] = 3;
// to iterate over identifiers of a list one needs to use the function members // the identifiers are returned as a lexicographically ordered string row-vector // here ["!", "hello", "world"] for(i in members(x)) { printf("%s %g\n", i, x.[i]); }
// occasionally one needs to check if there exists member of a list y = members(x); // y contains ["!", "hello", "world"] clear(x.["!"]); // remove member with identifier "!" from the list "x" for(i in y) { printf("%s %g\n", i, x.[i]); } // this produces error because x.["!"] does not exist
for(i in y) {
if (exist(x.[i])) { printf("%s %g\n", i, x.[i]); } // we print a member of the list "x" only if it exists
}
</lang>
Ruby
<lang ruby>myDict = { "hello" => 13, "world" => 31, "!" => 71 }
- iterating over key-value pairs:
myDict.each {|key, value| puts "key = #{key}, value = #{value}"}
- or
myDict.each_pair {|key, value| puts "key = #{key}, value = #{value}"}
- iterating over keys:
myDict.each_key {|key| puts "key = #{key}"}
- iterating over values:
myDict.each_value {|value| puts "value =#{value}"}</lang>
another way: <lang ruby>for key, value in myDict
puts "key = #{key}, value = #{value}"
end
for key in myDict.keys
puts "key = #{key}"
end
for value in myDict.values
puts "value = #{value}"
end</lang>
- Output:
key = hello, value = 13 key = world, value = 31 key = !, value = 71 key = hello key = world key = ! value = 13 value = 31 value = 71
Rust
<lang Rust>use std::collections::HashMap; fn main() {
let mut squares = HashMap::new(); squares.insert("one", 1i32); squares.insert("two", 4); squares.insert("three", 9); for key in squares.keys() { println!("Key {}", key); } for value in squares.values() { println!("Value {}", value); } for (key, value) in squares.iter() { println!("{} => {}", key, value); }
}</lang>
Scala
<lang Scala>val m = Map("Amsterdam" -> "Netherlands", "New York" -> "USA", "Heemstede" -> "Netherlands")
println(f"Key->Value: ${m.mkString(", ")}%s") println(f"Pairs: ${m.toList.mkString(", ")}%s") println(f"Keys: ${m.keys.mkString(", ")}%s") println(f"Values: ${m.values.mkString(", ")}%s")
println(f"Unique values: ${m.values.toSet.mkString(", ")}%s")</lang>
- Output:
Key->Value: Amsterdam -> Netherlands, New York -> USA, Heemstede -> Netherlands Pairs: (Amsterdam,Netherlands), (New York,USA), (Heemstede,Netherlands) Keys: Amsterdam, New York, Heemstede Values: Netherlands, USA, Netherlands Unique values: Netherlands, USA
Scheme
<lang Scheme>
- Create an associative array (hash-table) whose keys are strings
(define table (hash-table 'string=?
'("hello" . 0) '("world" . 22) '("!" . 999)))
- Iterate over the table, passing the key and the value of each entry
- as arguments to a function
(hash-table-for-each
table ;; Create by "partial application" a function that accepts 2 arguments, ;; the key and the value: (pa$ format #t "Key = ~a, Value = ~a\n"))</lang>
Output:
Key = !, Value = 999 Key = world, Value = 22 Key = hello, Value = 0
<lang Scheme>
- Iterate over the table and create a list of the keys and the
- altered values
(hash-table-map
table (lambda (key val) (list key (+ val 5000))))
- Create a new table that has the same keys but altered values.
(use gauche.collection) (map-to <hash-table>
(lambda (k-v) (cons (car k-v) (+ (cdr k-v) 5000))) table)
</lang>
To get a list of the keys or of the values of the table, use one of the following:
(hash-table-keys table) (hash-table-values table)
Seed7
<lang seed7>$ include "seed7_05.s7i";
const type: dictType is hash [string] integer; var dictType: myDict is dictType.value;
const proc: main is func
local var string: stri is ""; var integer: number is 0; begin myDict @:= ["hello"] 1; myDict @:= ["world"] 2; myDict @:= ["!"] 3;
# iterating over key-value pairs: for number key stri range myDict do writeln("key = " <& number <& ", value = " <& stri); end for;
# iterating over keys: for key stri range myDict do writeln("key = " <& stri); end for;
# iterating over values: for number range myDict do writeln("value = " <& number); end for; end func;</lang>
- Output:
key = 3, value = ! key = 1, value = hello key = 2, value = world key = ! key = hello key = world value = 3 value = 1 value = 2
Slate
In Slate, all associative mappings inherit from Mapping, so they all have the same protocol. Even Sequences obey it, in addition to their own protocol for collections with ordered integer-range keys. <lang slate>define: #pairs -> ({'hello' -> 1. 'world' -> 2. '!' -> 3. 'another!' -> 3} as: Dictionary). pairs keysAndValuesDo: [| :key :value |
inform: '(k, v) = (' ; key printString ; ', ' ; value printString ; ')'
].
pairs keysDo: [| :key |
inform: '(k, v) = (' ; key printString ; ', ' ; (pairs at: key) printString ; ')'
].
pairs do: [| :value |
inform: 'value = ' ; value printString
].</lang>
Smalltalk
<lang smalltalk>|pairs| pairs := Dictionary from: { 'hello' -> 1. 'world' -> 2. '!' -> 3. 'another!' -> 3 }.
"iterate over keys and values" pairs keysAndValuesDo: [ :k :v |
('(k, v) = (%1, %2)' % { k. v }) displayNl
].
"iterate over keys" pairs keysDo: [ :key |
('key = %1, value = %2' % { key. pairs at: key }) displayNl
].
"iterate over values" pairs do: [ :value |
('value = %1' % { value }) displayNl
].</lang>
We could also obtain a set of keys or a collection of values and iterate over them with "do:":
<lang smalltalk>(pairs keys) do: [ :k | "..." ]. (pairs values) do: [ :v | "..." ].</lang>
SNOBOL4
<lang SNOBOL4>* # Create sample table
t = table() t<'cat'> = 'meow' t<'dog'> = 'woof' t<'pig'> = 'oink'
- # Convert table to key/value array
a = convert(t,'array')
- # Iterate pairs
ploop i = i + 1; output = a<i,1> ' -> ' a<i,2> :s(ploop)
- # Iterate keys
kloop j = j + 1; output = a<j,1> :s(kloop)
- # Iterate vals
vloop k = k + 1; output = a<k,2> :s(vloop) end</lang>
Swift
<lang swift>let myMap = [ "hello": 13, "world": 31, "!" : 71 ]
// iterating over key-value pairs: for (key, value) in myMap {
println("key = \(key), value = \(value)")
}</lang>
Tcl
With Arrays
<lang tcl>array set myAry {
# list items here...
}
- Iterate over keys and values
foreach {key value} [array get myAry] {
puts "$key -> $value"
}
- Iterate over just keys
foreach key [array names myAry] {
puts "key = $key"
}
- There is nothing for directly iterating over just the values
- Use the keys+values version and ignore the keys</lang>
With Dictionaries
<lang tcl>set myDict [dict create ...]; # Make the dictionary
- Iterate over keys and values
dict for {key value} $myDict {
puts "$key -> $value"
}
- Iterate over keys
foreach key [dict keys $myDict] {
puts "key = $key"
}
- Iterate over values
foreach value [dict values $myDict] {
puts "value = $value"
}</lang>
TXR
<lang txr> @(do (defvar *h* (make-hash nil nil nil))
(each ((k '(a b c)) (v '(1 2 3))) (set [*h* k nil] v)) (dohash (k v *h*) (format t "~a -> ~a\n" k v))))</lang>
$ txr hash.txr c -> 3 b -> 2 a -> 1
UNIX Shell
Two shells have associative arrays, but they use different syntax to access their keys.
<lang bash>typeset -A a=([key1]=value1 [key2]=value2)
- just keys
printf '%s\n' "${!a[@]}"
- just values
printf '%s\n' "${a[@]}"
- keys and values
for key in "${!a[@]}"; do printf '%s => %s\n' "$key" "${a[$key]}" done</lang>
<lang bash>typeset -A a a=(key1 value1 key2 value2)
- just keys
print -l -- ${(k)a}
- just values
print -l -- ${(v)a}
- keys and values
printf '%s => %s\n' ${(kv)a}</lang>
Vala
<lang vala> using Gee;
void main(){
// declare HashMap var map = new HashMap<string, double?>();
// set 3 entries map["pi"] = 3.14; map["e"] = 2.72; map["golden"] = 1.62;
// iterate over (key,value) pair foreach (var elem in map.entries){ string name = elem.key; double num = elem.value;
stdout.printf("%s,%f\n", name, num);
}
// iterate over keys foreach (string key in map.keys){
stdout.printf("%s\n", key);
}
// iterate over values foreach (double num in map.values){
stdout.printf("%f\n", num);
}
} </lang>
Compile with flag:
--pkg gee-1.0
- Output:
e,2.720000 golden,1.620000 pi,3.140000 e golden pi 2.720000 1.620000 3.140000
Vim Script
<lang vim>let dict = {"apples": 11, "oranges": 25, "pears": 4}
echo "Iterating over key-value pairs" for [key, value] in items(dict)
echo key " => " value
endfor echo "\n"
echo "Iterating over keys" for key in keys(dict)
echo key
endfor echo "\n"
echo "Iterating over values" for value in values(dict)
echo value
endfor</lang>
- Output:
Iterating over key-value pairs oranges => 25 pears => 4 apples => 11 Iterating over keys oranges pears apples Iterating over values 25 4 11
Wart
<lang wart>h <- (table 'a 1 'b 2) each (key val) table
prn key " " val</lang>
- Output:
a 1 b 2
XPL0
<lang XPL0>include c:\cxpl\stdlib; char Dict(10,10); int Entries;
proc AddEntry(Letter, Greek); \Insert entry into associative array char Letter, Greek; [Dict(Entries,0):= Letter; StrCopy(Greek, @Dict(Entries,1)); Entries:= Entries+1; \(limit checks ignored for simplicity) ];
int I; [Entries:= 0; AddEntry(^A, "alpha"); AddEntry(^D, "delta"); AddEntry(^B, "beta"); AddEntry(^C, "gamma"); for I:= 0 to Entries-1 do
[ChOut(0, Dict(I,0)); ChOut(0, ^ ); Text(0, @Dict(I,1)); CrLf(0)];
]</lang>
- Output:
A alpha D delta B beta C gamma
zkl
<lang zkl>var d=D("A","alpha","D","delta", "B","beta", "C", "gamma"); d.keys.pump(Console.print,fcn(k){String(k,",")}) d.values.apply("toUpper").println(); d.makeReadOnly(); // can only iterate over k,v pairs if read only foreach k,v in (d){print(k,":",v,"; ")}</lang>
- Output:
A,B,C,D, L("ALPHA","BETA","GAMMA","DELTA") A:alpha; B:beta; C:gamma; D:delta;
- Programming Tasks
- Basic language learning
- Iteration
- Data Structures
- Ada
- Aime
- App Inventor
- AutoHotkey
- AWK
- Babel
- BASIC256
- BBC BASIC
- Bracmat
- Brat
- C
- C++
- C sharp
- Chapel
- Clojure
- CoffeeScript
- Common Lisp
- D
- Dao
- Delphi
- E
- Elena
- Erlang
- F Sharp
- Factor
- Fantom
- Forth
- Forth Foundation Library
- Go
- Groovy
- Harbour
- Haskell
- Icon
- Unicon
- J
- Java
- JavaScript
- Jq
- Julia
- K
- Lang5
- Lasso
- LFE
- Liberty BASIC
- Lua
- M4
- Maple
- Mathematica
- MATLAB
- Octave
- Maxima
- NetRexx
- NewLISP
- Nim
- Oberon-2
- Objeck
- Objective-C
- OCaml
- OoRexx
- Oz
- PARI/GP
- Perl
- Perl 6
- PHP
- PicoLisp
- Pike
- PostScript
- PowerShell
- Prolog
- PureBasic
- Python
- R
- Racket
- REXX
- RLaB
- Ruby
- Rust
- Scala
- Scheme
- Seed7
- Slate
- Smalltalk
- SNOBOL4
- Swift
- Tcl
- TXR
- UNIX Shell
- Vala
- Gee
- Vim Script
- Wart
- XPL0
- Zkl
- Applesoft BASIC/Omit
- Brainf***/Omit
- Integer BASIC/Omit
- TI-89 BASIC/Omit