From d41cfae07b785b149ab62147d6717b844b0e12f4 Mon Sep 17 00:00:00 2001 From: David Date: Thu, 27 Feb 2014 01:44:05 +0100 Subject: [PATCH] Implement maphash function --- src/hash-table.lisp | 23 ++++++++++++++++++----- tests/hash-tables.lisp | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 5 deletions(-) diff --git a/src/hash-table.lisp b/src/hash-table.lisp index 301addd..e47384e 100644 --- a/src/hash-table.lisp +++ b/src/hash-table.lisp @@ -22,6 +22,10 @@ ;;; `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 @@ -73,15 +77,17 @@ `(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)) @@ -115,3 +121,10 @@ (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) diff --git a/tests/hash-tables.lisp b/tests/hash-tables.lisp index 3dc7528..130ca98 100644 --- a/tests/hash-tables.lisp +++ b/tests/hash-tables.lisp @@ -20,3 +20,36 @@ (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)))) -- 1.7.10.4