Associative array/Iteration: Difference between revisions

From Rosetta Code
Content added Content deleted
Line 209: Line 209:


=={{header|OCaml}}==
=={{header|OCaml}}==
Association list:
<lang ocaml>#!/usr/bin/env ocaml
<lang ocaml>#!/usr/bin/env ocaml


Line 220: Line 221:


(* iterate over values *)
(* iterate over values *)
Array.iter (fun (_,v) -> Printf.printf "value: %d\n" v) map ;;</lang>
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>


=={{header|Perl}}==
=={{header|Perl}}==

Revision as of 09:46, 10 August 2009

Task
Associative array/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.

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> Sample output:

! 3
hello 1
world 2

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>

C++

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

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

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>

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>

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'

OCaml

Association list: <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>

Perl

<lang perl>#! /usr/bin/perl use strict;

my %pairs = ( "hello" => 13, "world" => 31, "!" => 71 );

  1. iterate over pairs

while ( my ($k, $v) = each %pairs) {

   print "(k,v) = ($k, $v)\n";

}

  1. iterate over keys

foreach my $key ( keys %pairs ) {

   print "key = $key, value = $pairs{$key}\n";

}

  1. iterate over values

foreach my $val ( values %pairs ) {

   print "value = $val\n";

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

Python

<lang python>myDict = { "hello": 13, "world": 31, "!"  : 71 }

  1. iterating over key-value pairs:

for key, value in myDict.items():

   print ("key = %s, value = %s" % (key, value))
  1. iterating over keys:

for key in myDict:

   print ("key = %s" % key)
  1. (is a shortcut for:)

for key in myDict.keys():

   print ("key = %s" % key)
  1. iterating over values:

for value in myDict.values():

   print ("value = %s" % value)</lang>

Ruby

<lang ruby>myDict = { "hello" => 13, "world" => 31, "!" => 71 }

  1. iterating over key-value pairs:

myDict.each {|key, value| puts "key = #{key}, value = #{value}"}

  1. or

myDict.each_pair {|key, value| puts "key = #{key}, value = #{value}"}

  1. iterating over keys:

myDict.each_key {|key| puts "key = #{key}"}

  1. iterating over values:

myDict.each_value {|value| puts "value =#{value}"}</lang>

Smalltalk

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

Tcl

With Arrays

<lang tcl>array set myAry {

   # list items here...

}

  1. Iterate over keys and values

foreach {key value} [array get myAry] {

   puts "$key -> $value"

}

  1. Iterate over just keys

foreach key [array names myAry] {

   puts "key = $key"

}

  1. There is nothing for directly iterating over just the values
  2. Use the keys+values version and ignore the keys</lang>

With Dictionaries

Works with: Tcl version 8.5

<lang tcl>set myDict [dict create ...]; # Make the dictionary

  1. Iterate over keys and values

dict for {key value} $myDict {

   puts "$key -> $value"

}

  1. Iterate over keys

foreach key [dict keys $myDict] {

   puts "key = $key"

}

  1. Iterate over values

foreach value [dict values $myDict] {

   puts "value = $value"

}</lang>