3cf5a5efd686

Add iterate (collect-set ...) clause
[view raw] [browse files]
author Steve Losh <steve@stevelosh.com>
date Mon, 25 Feb 2019 22:07:11 -0500
parents ba5b4efb5872
children dc630773f98a 72093637ac8b
branches/tags (none)
files losh.asd package.lisp src/iterate.lisp

Changes

--- a/losh.asd	Sat Feb 23 22:46:27 2019 -0500
+++ b/losh.asd	Mon Feb 25 22:07:11 2019 -0500
@@ -54,7 +54,9 @@
                                                  "hash-tables"))
 
                  (:file "iterate" :depends-on ("control-flow"
-                                               "sequences"))
+                                               "sequences"
+                                               "iterate-pre"
+                                               "hash-sets"))
                  (:file "gnuplot" :depends-on ("control-flow"
                                                "debugging"
                                                "sequences"))
--- a/package.lisp	Sat Feb 23 22:46:27 2019 -0500
+++ b/package.lisp	Mon Feb 25 22:07:11 2019 -0500
@@ -318,6 +318,7 @@
 (defpackage :losh.iterate
   (:use :cl :iterate :losh.quickutils
     :losh.iterate-pre
+    :losh.hash-sets
     :losh.control-flow ;; always needed because we need a single RECURSIVELY symbol
     :losh.sequences)
   (:documentation "Custom `iterate` drivers and clauses.")
@@ -327,6 +328,7 @@
     :anding
     :averaging
     :collect-hash
+    :collect-set
     :cycling
     :every-nth
     :for-nested
--- a/src/iterate.lisp	Sat Feb 23 22:46:27 2019 -0500
+++ b/src/iterate.lisp	Mon Feb 25 22:07:11 2019 -0500
@@ -596,6 +596,28 @@
          (with ,hash-table = (make-hash-table :test ,test))
          (setf (gethash ,key ,hash-table) ,value)))))
 
+(defmacro-clause (COLLECT-SET element &optional
+                  INTO var
+                  TEST (test '#'eql))
+  "Collect elements into a hash set at `var`.
+
+  If `var` is omitted the hash set will be returned instead.
+
+  `test` specifies the test used for the hash set.
+
+  Example:
+
+    (iterate (for y :in '(a b a))
+             (collect-set y))
+    ; => {a b}
+
+  "
+  (let ((hash-set (or var iterate::*result-var*)))
+    `(progn
+       (with ,hash-set = (make-hash-set :test ,test))
+       (hset-insert! ,hash-set ,element))))
+
+
 (defmacro-clause (ORING expr &optional INTO var)
   (let ((result (or var iterate::*result-var*)))
     `(reducing ,expr :by #'or :into ,result :initial-value nil)))