#lang scheme/base
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; BASE.plt - common routines that are shared by all other bzlib modules
;; in a way, base.plt is the most fundamental module of the whole bzlib stack
;; and as such it also is the lowest level code.  We are not likely to
;; fix the code any time soon, and hence any of the functions here are
;; explicitly likely to be obsoleted or moved elsewhere.
;; Proceed with caution.
;; Bonzai Lab, LLC.  All rights reserved.
;; Licensed under LGPL.
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; - basic functionalities that has to do with list processing.
;; yc 9/8/2009 - first version
;; yc 9/25/2009 - moved group from bzlib/dbd-memcached/dht to here; exported scheme/list
(require "" scheme/list)

(define (assoc/cdr key alist (default #f))
  (if-it (assoc key alist)
         (cdr it)

(define (assoc/s key alist (default '()))
  (let ((it (filter (lambda (kv)
                      (equal? (car kv) key))
    (if (null? it) default it)))

;; this function is a combo of member & assoc
;; it's useful when we have a malformed alist, where when the
;; pair has no value, the key is retained
;; (or when there is no key, the value is retained)
(define (assoc* key lst (default #f))
  (define (helper rest)
    (cond ((null? rest) default)
          ;; assoc behavior
          ((and (pair? (car rest))
                (equal? key (caar rest)))
           (car rest))
          ;; member behavior
          ((and (not (pair? (car rest)))
                (equal? key (car rest)))
           (helper (cdr rest)))))
  ;; (trace helper)
  (helper lst))

(define (assoc*/cdr key lst (default #f))
  (if-it (assoc* key lst)
         (cdr it)

(define (group alist)
  ;; for each alist with the same key - group them together!!
  (foldl (lambda (kv interim)
           (if-it (assoc (car kv) interim) ;; the key already exists...
               (cons (cons (car it) (cons (cdr kv) (cdr it)))
                     (filter (lambda (kv)
                               (not (equal? it kv))) interim))
               (cons (list (car kv) (cdr kv)) interim)))

 (assoc/cdr (->* (any/c list?)
 (assoc/s (->* (any/c list?)
 (assoc* (->* (any/c list?)
 (assoc*/cdr (->* (any/c list?)
 (group (-> pair? any))
(provide (all-from-out scheme/list))