Browse code
feat: add hash-join
Edward Langley authored on 22/10/2023 18:15:22
Showing 2 changed files
Showing 2 changed files
... | ... |
@@ -423,6 +423,26 @@ |
423 | 423 |
(reverse (cdr it)))) |
424 | 424 |
(alexandria:hash-table-alist groups))))) |
425 | 425 |
|
426 |
+(defun hash-join (probe join-fn &key (test 'eql) (key 'car)) |
|
427 |
+ (let* ((lookup (make-hash-table :test test :size (length probe))) |
|
428 |
+ (lookup-fn (functionalize lookup))) |
|
429 |
+ (map nil |
|
430 |
+ (lambda (it) |
|
431 |
+ (setf (gethash (funcall key it) |
|
432 |
+ lookup) |
|
433 |
+ it)) |
|
434 |
+ probe) |
|
435 |
+ (lambda (collection) |
|
436 |
+ (map (etypecase collection |
|
437 |
+ (list 'list) |
|
438 |
+ (vector 'vector) |
|
439 |
+ (sequence 'list)) |
|
440 |
+ (lambda (it) |
|
441 |
+ (let* ((key-value (funcall key it)) |
|
442 |
+ (matching-probe (funcall lookup-fn key-value))) |
|
443 |
+ (funcall join-fn it matching-probe))) |
|
444 |
+ collection)))) |
|
445 |
+ |
|
426 | 446 |
#+nil |
427 | 447 |
(defmacro <> (arity &rest funs) |
428 | 448 |
(let ((arg-syms (loop repeat arity collect (gensym)))) |