Associative arrays/Iteration

From Rosetta Code

Jump to: navigation, search
Task
Associative arrays/Iteration
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.

Contents

[edit] 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;

Sample output:

! 3
hello 1
world 2

[edit] AutoHotkey

Works with: AutoHotkey_L

From the documentation
; 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

[edit] AWK

In AWK "arrays" are always associative arrays, and the only way to iterate over them is by keys (indexes in the AWK terminology)

BEGIN {
a["hello"] = 1
a["world"] = 2
a["!"] = 3
 
# iterate over keys
for(key in a) {
print key, a[key]
}
}

[edit] C

Library: Judy

We can easily iterate over pair of keys (indexes) and values.

#include <stdio.h>
#include <Judy.h>
 
#define MAXLINELEN 256
 
int main()
{
Pvoid_t assoc_arr = (Pvoid_t) NULL;
PWord_t val;
 
uint8_t idx[MAXLINELEN];
 
// insert some values
JSLI(val, assoc_arr, "hello");
*val = 4;
JSLI(val, assoc_arr, "world");
*val = 8;
JSLI(val, assoc_arr, "!");
*val = 16;
 
// iterate over indexes-values
idx[0] = '\0';
 
JSLF(val, assoc_arr, idx);
while(val != NULL) {
printf("'%s' -> %d\n", idx, *val);
JSLN(val, assoc_arr, idx);
}
 
JudySLFreeArray(&assoc_arr, PJE0);
return 0;
}

[edit] C++

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 a pair<std::string, int>
std::string key = it->first;
int value = it->second;
std::cout << "key = " << key << ", value = " << value << std::endl;
}

[edit] C#

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());
}
}
}
}
 

[edit] 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))

[edit] Common Lisp

Common Lisp has three common idioms for associating keys with values: association lists (alists), property lists (plists), and hash tables.

[edit] 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.

;; 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))

[edit] 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.

(loop for (key value) on plist :by 'cddr
do (format t "~&Key: ~a, Value: ~a." key value))

[edit] 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.

(maphash (lambda (key value)
(format t "~&Key: ~a, Value: ~a." key value))
hash-table)

The loop construct also supports extracting key/value pairs from hash tables.

(loop for key being each hash-key of hash-table using (hash-value value)
do (format t "~&Key: ~a, Value: ~a." key value))

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.

(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)))))

[edit] D

Works with: D version 2

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);
}

[edit] Dao

 
m = { 'def' => 1, 'abc' => 2 }
for( kv in m ) io.writeln( kv );
for( k in m.keys(); v in m.values() ) io.writeln( k, v )
 

[edit] 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 (_).

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 .`)
}

[edit] Factor

H{ { "hi" "there" } { "a" "b" } } [ ": " glue print ] assoc-each

There's also assoc-map, assoc-find, assoc-filter and many more.

[edit] 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)
}

[edit] Haskell

with Data.Map:

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

[edit] Icon and Unicon

[edit] 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

Sample output:

->aai
        A -> a
        B -> b
        C -> c
        D -> d
        E -> e
Keys: C E B D A
Values: c e b d a

[edit] Unicon

The Icon solution also works in Unicon.

[edit] 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
nl__example 0
Values
get__example each nl__example 0
Both keys and values
(,&< get__example) each nl__example 0

Note that this last is not likely to be useful in any practical context outside of learning the language.

[edit] 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);
}

[edit] JavaScript

JavaScript does not have associative arrays. You can add properties to an empty object, and that works basically the same way:

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;
 
var output;
for (var key in myhash) {
output += "key is: " + key;
output += " => ";
output += "value is: " + myhash[key]; // cannot use myhash.key, that would be myhash["key"]
output += "\n";
}

To iterate over values in JavaScript 1.6+:

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;
 
var output;
for each (var val in myhash) {
output += "value is: " + val;
output += "\n";
}

[edit] Lua

local table = {
["foo"] = "bar",
["baz"] = 6,
42 = 7,
}
for key,val in pairs(table) do
print(string.format("%s: %s\n", key, val)
end

[edit] 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)
')

Output:

key-value pairs
`wow',`flame'
`bow',`7'

keys
`wow'
`bow'

values
`flame'
`7'

[edit] Objective-C

Works with: Objective-C version 2.0+

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);
}

Works with: Objective-C version <2.0

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);
}

[edit] OCaml

Association list:

#!/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 ;;

Hash table:

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" ;;

Functional binary search tree:

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" ;;

[edit] 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

[edit] Perl

#! /usr/bin/perl
use strict;
 
my %pairs = ( "hello" => 13,
"world" => 31,
"!" => 71 );
 
# iterate over pairs
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";
}
 
# iterate over values
foreach my $val ( values %pairs ) {
print "value = $val\n";
}

[edit] Perl 6

Works with: Rakudo version #21 "Seattle"

my %pairs = hello => 13, world => 31, '!' => 71;
 
for %pairs.kv -> $k, $v {
say "(k,v) = ($k, $v)";
}
 
say "key = $_" for %pairs.keys;
 
say "value = $_" for %pairs.values;

[edit] 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";
}
?>

[edit] PicoLisp

[edit] Using properties

(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)

[edit] Using an index tree

(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)

[edit] PureBasic

Hashes are a built-in type called Map in Purebasic.

NewMap dict.s()
dict("de") = "German"
dict("en") = "English"
dict("fr") = "French"
 
ForEach dict()
Debug MapKey(dict()) + ":" + dict()
Next

[edit] 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)

[edit] PowerShell

Using the following hash table:

$h = @{ 'a' = 1; 'b' = 2; 'c' = 3 }

Iterating over the key/value pairs is slightly cumbersome as it requires an explicit call to GetEnumerator:

$h.GetEnumerator() | ForEach-Object { Write-Host Key: $_.Name, Value: $_.Value }

A foreach statement can also be used:

foreach ($e in $h.GetEnumerator()) {
Write-Host Key: $e.Name, Value: $e.Value
}

Iterating over the keys:

$h.Keys | ForEach-Object { Write-Host Key: $_ }
 
foreach ($k in $h.Keys) {
Write-Host Key: $k
}

Iterating over the values:

$h.Values | ForEach-Object { Write-Host Value: $_ }
 
foreach ($v in $h.Values) {
Write-Host Value: $v
}

[edit] R

R does not have a built-in concept of key-value pairs, however vectors can have named elements, which is close.

x <- c(hello=1, world=2, "!"=3)
print(x)
hello world     ! 
    1     2     3
print(names(x))
"hello" "world" "!"
print(unname(x))
1 2 3

[edit] RLaB

Associative arrays are called lists in 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
}
 
 
 

[edit] 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}"}

[edit] Scala

val m=Map("Hello"->13, "world"->31, "!"->71)
 
println("Keys:")
m.keys foreach println
 
println("\nValues:")
m.values foreach println
 
println("\nPairs:")
m foreach println
 
println("\nKey->Value:")
for((k,v)<-m) println(k+"->"+v)

[edit] 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.

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
].

[edit] Smalltalk

Works with: GNU 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
].

We could also obtain a set of keys or a collection of values and iterate over them with "do:":

(pairs keys) do: [ :k | "..." ].
(pairs values) do: [ :v | "..." ].

[edit] SNOBOL4

Works with: Macro Spitbol Works with: Snobol4+ Works with: CSnobol

*       # 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

[edit] Tcl

[edit] With Arrays

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

[edit] With Dictionaries

Works with: Tcl version 8.5

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"
}

[edit] Zsh

typeset -A a
a=(key1 value1 key2 value2)
 
# just keys
print -l -- ${(k)a}
 
# just values
print -l -- ${(v)a}
 
# keys and values
print -l -- ${(kv)a}
 
Personal tools
Support