refactor loops to be less slovenly

pull/12/merge
Matthew Butterick 9 years ago
parent 78c788ae17
commit d77eb3fa68

@ -15,87 +15,75 @@
(dropf-right (dropf xs test-proc) test-proc)) (dropf-right (dropf xs test-proc) test-proc))
(define (slicef-and-filter-split-helper xs pred [drop-negated? #f])
(let loop ([xs xs][negating? #f])
(cond
[(empty? xs) empty]
[else
(define loop-pred (if negating? (compose1 not pred) pred))
(define-values (loop-pred-xs rest) (splitf-at xs loop-pred))
(define subxs (if (and negating? drop-negated?) empty loop-pred-xs))
(if (empty? subxs)
(loop rest (not negating?))
(cons subxs (loop rest (not negating?))))])))
(define+provide+safe (slicef xs pred) (define+provide+safe (slicef xs pred)
(list? procedure? . -> . list-of-lists?) (list? procedure? . -> . list-of-lists?)
(define-values (last-list list-of-lists last-negating) (slicef-and-filter-split-helper xs pred))
(for/fold ([current-list empty]
[list-of-lists empty]
[negating? #f])
([x (in-list xs)])
(define current-pred (if negating? (λ (x) (not (pred x))) pred))
(if (current-pred x)
(values (cons x current-list) list-of-lists negating?)
(values (cons x null) (if (not (empty? current-list))
(cons (reverse current-list) list-of-lists)
list-of-lists) (not negating?)))))
(reverse (cons (reverse last-list) list-of-lists)))
(define+provide+safe (slicef-at xs pred [force? #f]) (define+provide+safe (slicef-at xs pred [force? #f])
((list? procedure?) (boolean?) . ->* . list-of-lists?) ((list? procedure?) (boolean?) . ->* . list-of-lists?)
(define-values (last-list list-of-lists) (let loop ([xs xs])
(for/fold (cond
([current-list empty][list-of-lists empty]) [(empty? xs) empty]
([x (in-list xs)]) [(pred (car xs))
(if (pred x) (define-values (not-pred-xs rest) (splitf-at (cdr xs) (compose1 not pred)))
(values (cons x null) (if (not (empty? current-list)) (cons (cons (car xs) not-pred-xs) (loop rest))]
(cons (reverse current-list) list-of-lists) [else
list-of-lists)) (define-values (not-pred-xs rest) (splitf-at xs (compose1 not pred)))
(values (cons x current-list) list-of-lists)))) (if force?
(let ([list-of-lists (reverse (if (empty? last-list) (loop rest)
list-of-lists (cons not-pred-xs (loop rest)))])))
(cons (reverse last-list) list-of-lists)))])
(if (and force? (not (empty? list-of-lists)) (not (pred (caar list-of-lists))))
(cdr list-of-lists)
list-of-lists)))
(define+provide+safe (slicef-after xs pred) (define+provide+safe (slicef-after xs pred)
(list? procedure? . -> . list-of-lists?) (list? procedure? . -> . list-of-lists?)
(define-values (last-list list-of-lists) (let loop ([xs xs])
(for/fold ([current-list empty][list-of-lists empty]) (cond
([x (in-list xs)]) [(empty? xs) empty]
(if (pred x) [else
(values empty (cons (reverse (cons x current-list)) list-of-lists)) (define-values (not-pred-xs rest) (splitf-at xs (compose1 not pred)))
(values (cons x current-list) list-of-lists)))) (if (pair? rest)
(reverse (if (empty? last-list) (let ([must-be-pred-x (car rest)])
list-of-lists (cons (append not-pred-xs (list must-be-pred-x)) (loop (cdr rest))))
(cons (reverse last-list) list-of-lists)))) not-pred-xs)])))
(define+provide+safe (slice-at xs len [force? #f]) (define+provide+safe (slice-at xs len [force? #f])
((list? (and/c integer? positive?)) (boolean?) . ->* . list-of-lists?) ((list? (and/c integer? positive?)) (boolean?) . ->* . list-of-lists?)
(define-values (last-list list-of-lists) (unless (and (integer? len) (positive? len))
(for/fold ([current-list empty][list-of-lists empty]) (raise-argument-error 'slice-at "positive integer for sublist length" len))
([x (in-list xs)][i (in-naturals)]) (let loop ([xs xs])
(if (= (modulo (add1 i) len) 0) (cond
(values empty (cons (reverse (cons x current-list)) list-of-lists)) [(< (length xs) len) (if (or force? (empty? xs)) empty (list xs))]
(values (cons x current-list) list-of-lists)))) [else
(reverse (if (or (empty? last-list) (and force? (not (= len (length last-list))))) (define-values (subxs rest) (split-at xs len))
list-of-lists (cons subxs (loop rest))])))
(cons (reverse last-list) list-of-lists))))
(define+provide+safe (filter-split xs pred) (define+provide+safe (filter-split xs pred)
(list? predicate/c . -> . list-of-lists?) (list? predicate/c . -> . list-of-lists?)
(define-values (last-list list-of-lists) ;; same idea as slicef, but the negated items are dropped(-
(for/fold ([current-list empty][list-of-lists empty]) (slicef-and-filter-split-helper xs (compose1 not pred) 'drop-negated))
([x (in-list xs)])
(if (pred x)
(values empty (if (not (empty? current-list))
(cons (reverse current-list) list-of-lists)
list-of-lists))
(values (cons x current-list) list-of-lists))))
(reverse (if (not (empty? last-list))
(cons (reverse last-list) list-of-lists)
list-of-lists)))
(define+provide+safe (frequency-hash xs) (define+provide+safe (frequency-hash xs)
(list? . -> . hash?) (list? . -> . hash?)
(define counter (make-hash)) (define counter (make-hash))
(for ([item (in-list xs)]) (for ([item (in-list xs)])
(hash-update! counter item (λ(v) (add1 v)) (λ _ 0))) (hash-update! counter item add1 0))
counter) counter)
(define (->list x) (define (->list x)

Loading…
Cancel
Save