update sugar/list and docs

pull/2/head
Matthew Butterick 10 years ago
parent 66dc6e0e6e
commit ac469d6d3f

@ -1,5 +1,5 @@
#lang racket/base #lang racket/base
(require racket/list) (require racket/list racket/set)
(require "define.rkt" "len.rkt" "coerce.rkt") (require "define.rkt" "len.rkt" "coerce.rkt")
(define+provide/contract (trimf xs test-proc) (define+provide/contract (trimf xs test-proc)
@ -28,7 +28,7 @@
(loop rest (cons item acc)))))) (loop rest (cons item acc))))))
(define+provide/contract (count-incidence x) (define+provide/contract (frequency-hash x)
(list? . -> . hash?) (list? . -> . hash?)
(define counter (make-hash)) (define counter (make-hash))
(for ([item (flatten x)]) (for ([item (flatten x)])
@ -36,22 +36,26 @@
counter) counter)
(define+provide/contract (members-unique? x) (define+provide/contract (members-unique? x)
(any/c . -> . boolean?) ((or/c list? vector? string?) . -> . boolean?)
(cond (cond
[(list? x) (= (len (remove-duplicates x)) (len x))] [(list? x) (= (len (remove-duplicates x)) (len x))]
[(vector? x) (members-unique? (vector->list x))] [(vector? x) (->list x)]
[(string? x) (members-unique? (string->list x))] [(string? x) (string->list x)]
[else (error (format "members-unique cannot be determined for ~a" x))])) [else (error (format "members-unique? cannot be determined for ~a" x))]))
(define+provide/contract (members-unique?/error x) (define+provide/contract (members-unique?/error x)
(any/c . -> . boolean?) (any/c . -> . boolean?)
(define result (members-unique? x)) (define result (members-unique? x))
(if (not result) (if (not result)
(let* ([duplicate-keys (filter-not empty? (hash-map (count-incidence x) (let* ([duplicate-keys (filter-not empty? (hash-map (frequency-hash x)
(λ(k v) (if (> v 1) k '()))))]) (λ(k v) (if (> v 1) k '()))))])
(error (string-append (if (= (len duplicate-keys) 1) (error (string-append "members-unique? failed because " (if (= (len duplicate-keys) 1)
"item isnt" "item isnt"
"items arent") " unique:") duplicate-keys)) "items arent") " unique:") duplicate-keys))
result)) result))

@ -0,0 +1,76 @@
#lang scribble/manual
@(require scribble/eval (for-label racket sugar))
@(define my-eval (make-base-eval))
@(my-eval `(require sugar))
@title{List}
@defmodule[sugar/list]
@defproc[
(trimf
[lst list?]
[pred procedure?])
list?]
Drop elements from each end of @racket[_lst] that satisfy @racket[_pred]. Exactly equivalent to @racket[(dropf-right (dropf _lst _pred) _pred)].
@examples[#:eval my-eval
(trimf '(1 2 3 a b c 4 5 6) integer?)
(trimf '(1 2 3 a b c) integer?)
(trimf '(a b c) integer?)
(trimf '(a b c 1 2 3 d e f) integer?)]
@defproc[
(filter-split
[lst list?]
[pred procedure?])
(listof list?)]
Like @racket[string-split], but for lists. Drop elements from anywhere in @racket[_lst] that satisfy @racket[_pred] — ends, middle, you name it — and return a list of the sublists that remain.
@examples[#:eval my-eval
(filter-split '(1 a b c 2 d e f 3) integer?)
(filter-split '(1 a b c 2 d e f 3) (compose not integer?))
(filter-split '(a b c 1 2 3 d e f) integer?)
(filter-split '(a b c 1 2 3 d e f) (compose not integer?))]
@defproc[
(frequency-hash
[lst list?])
hash?]
Count the frequency of each element in @racket[_lst], and return a hash whose keys are the unique elements of @racket[_lst], and each value is the frequency of that element within @racket[_lst].
@examples[#:eval my-eval
(frequency-hash '(a b b c c c))
(frequency-hash '(c b c a b c))
]
@defproc[
(members-unique?
[container (or/c list? vector? string?)])
boolean?]
Return @racket[#t] if every element in @racket[_container] is unique, otherwise @racket[#f].
@examples[#:eval my-eval
(members-unique? '(a b c d e f))
(members-unique? '(a b c d e f a))
]
@defproc[
(members-unique?/error
[container (or/c list? vector? string?)])
boolean?]
Same as @racket[members-unique?], but if the members are not unique, raises a descriptive error rather than returning @racket[#f].
@examples[#:eval my-eval
(members-unique?/error '(a b c d e f))
(members-unique?/error '(a b c d e f a))
(members-unique?/error '(a b c d e f a b))
]

@ -28,6 +28,8 @@ A collection of small functions to help make Racket code simpler & more readable
@include-section["len.scrbl"] @include-section["len.scrbl"]
@include-section["list.scrbl"]
@include-section["license.scrbl"] @include-section["license.scrbl"]
@index-section[] @index-section[]

@ -93,9 +93,9 @@
(check-false ("foobar" . ends-with? . "foo")) (check-false ("foobar" . ends-with? . "foo"))
; (check-equal? (trim (list "\n" " " 1 2 3 "\n") whitespace?) '(1 2 3)) ; (check-equal? (trim (list "\n" " " 1 2 3 "\n") whitespace?) '(1 2 3))
(check-equal? (trim (list 1 3 2 4 5 6 8 9 13) odd?) '(2 4 5 6 8)) (check-equal? (trimf (list 1 3 2 4 5 6 8 9 13) odd?) '(2 4 5 6 8))
;(check-equal? (splitf-at* '("foo" " " "bar" "\n" "\n" "ino") whitespace?) '(("foo")("bar")("ino"))) ;(check-equal? (filter-split '("foo" " " "bar" "\n" "\n" "ino") whitespace?) '(("foo")("bar")("ino")))
(check-equal? (splitf-at* '(1 2 3 4 5 6) even?) '((1)(3)(5))) (check-equal? (filter-split '(1 2 3 4 5 6) even?) '((1)(3)(5)))
(check-equal? (filter-tree string? '(p)) null) (check-equal? (filter-tree string? '(p)) null)

Loading…
Cancel
Save