# HG changeset patch # User Steve Losh # Date 1551150431 18000 # Node ID 3cf5a5efd686fa5e3cf81fb9c881dbc82324a459 # Parent ba5b4efb5872324e015061419d854ad2cab060c1 Add iterate (collect-set ...) clause diff -r ba5b4efb5872 -r 3cf5a5efd686 losh.asd --- 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")) diff -r ba5b4efb5872 -r 3cf5a5efd686 package.lisp --- 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 diff -r ba5b4efb5872 -r 3cf5a5efd686 src/iterate.lisp --- 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)))