Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In guile scheme, how can I iterate a list of key-value pairs (i.e. a Hash map)?

I'm playing around with guile to try and get familiar with pure functional programming concepts. Before I can do anything useful with any language, I need to understand some basic data structures and how to manipulate them effectively... in particular, enumerable data structures.

I can iterate a list like this (I'm not sure if I'm indenting this correctly or not):

(map (lambda (v)
       (display (string-append v "\n"))
     '(1 2 3))
=>
1
2
3

What does a hash table/hash map look like in scheme? Is there a real data structure to represent one, or do it come down to making a list of lists? In which case, how do you get the key and value as separate variables from the inner list?

Obviously this is wrong, since the lambda expects one value, not two:

(map (lambda (key value)
       (display (string-append key " => " value))
     '('("one" 1) '("two" 2) '("three" 3)))

The Ruby equivalent of what I'm trying to do would be:

{ "one" => 1, "two" => 2, "three" => 3 }.map do |key, value|
  puts "#{key} => #{value}"
end
like image 637
d11wtq Avatar asked Nov 15 '11 01:11

d11wtq


1 Answers

If you are using R6RS hashtables, you can use the hashtable-keys and hashtable-entries functions.

If you're using Guile's native hashtables, you can use hash-map->list, hash-for-each, hash-for-each-handle, or hash-fold.

So for your example, using Guile's hash-for-each, you'd do:

(use-modules (ice-9 hash-table))
(define my-hash (make-hash-table))
(hash-set! my-hash "one" 1)
(hash-set! my-hash "two" 2)
(hash-set! my-hash "three" 3)
(hash-for-each (lambda (key value)
                 (format #t "~a => ~a~%" key value))
               my-hash)
like image 109
Chris Jester-Young Avatar answered Nov 11 '22 01:11

Chris Jester-Young