Implement maphash function
authorDavid <davazp@debian>
Thu, 27 Feb 2014 00:44:05 +0000 (01:44 +0100)
committerDavid <davazp@debian>
Thu, 27 Feb 2014 00:44:05 +0000 (01:44 +0100)
src/hash-table.lisp
tests/hash-tables.lisp

index 301addd..e47384e 100644 (file)
 ;;; `equalp').
 ;;;
 
+;;; Additionally, we want to iterate across the hash table
+;;; key-values. So we use a cons (key  . value)
+;;; as value in the Javascript object. It implicitly gives the
+;;; inverse mapping of strings to our objects.
 
 ;;; If a hash table has `eq' as test, we need to generate unique
 ;;; strings for each Lisp object. To do this, we tag the objects with
     `(hash-table ,hash-fn ,(new))))
 
 (defun gethash (key hash-table &optional default)
-  (let ((obj (caddr hash-table))
-        (hash (funcall (cadr hash-table) key)))
-    (values (oget obj hash)
-            (in hash obj))))
+  (let* ((obj (caddr hash-table))
+        (hash (funcall (cadr hash-table) key))
+        (exists (in hash obj)))
+    (if exists
+       (values (cdr (oget obj hash)) t)
+       (values default nil))))
 
 (defun sethash (new-value key hash-table)
   (let ((obj (caddr hash-table))
         (hash (funcall (cadr hash-table) key)))
-    (oset new-value obj hash)
+    (oset (cons key new-value) obj hash)
     new-value))
 
 
                   (incf count))
                 (caddr hash-table))
     count))
+
+
+(defun maphash (function hash-table)
+  (map-for-in (lambda (x)
+               (funcall function (car x) (cdr x)))
+             (caddr hash-table))
+  nil)
index 3dc7528..130ca98 100644 (file)
   (test (null (gethash "foo" ht))))
 
 
+;;; MAPHASH
+
+(let ((ht (make-hash-table))
+      (count 0))
+  (maphash (lambda (key value)
+            (declare (ignore key value))
+            (inct count))
+          ht)
+  (test (zerop count)))
+
+(let ((ht (make-hash-table))
+      (count 0))
+  (setf (gethash :x ht) 10)
+  (maphash (lambda (key value)
+            (setq count (1+ count)))
+          ht)
+  (test (= count 1)))
+
+(let ((ht (make-hash-table)))
+  (setf (gethash :x ht) 10)
+  (setf (gethash :y ht) 20)
+  (maphash (lambda (key value)
+            (when (eq key :x)
+              (test (= value 10)))
+            (when (eq key :y)
+              (test (= value 20))))
+          ht))
+
+(let ((ht (make-hash-table)))
+  (test
+   (eq nil (maphash (lambda (key value)
+                     (declare (ignore key value)))
+                   ht))))