-
-
Save chansey97/69a675bc9b10d3db562c72eafe53ef98 to your computer and use it in GitHub Desktop.
Uniq for Racket lists
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#lang racket/base | |
(provide uniq) | |
;;; | |
;;; Uniq | |
;;; | |
; The function uniq takes a list as input and returns a new list: | |
; adjacent elements are compared and omits any repeated elements. | |
; In other words, uniq works like the Unix utility uniq, but on list. | |
; The keywords #:count, #:repeats-only? and #:uniques-only? can | |
; be used to change the default behaviour. | |
; If #:count is present the output list will contain elements | |
; of the form (list x frequency-of-x). | |
; If #:repeats-only? is present, only the repeated elements will | |
; be in the output. | |
; If #:uniques-only? is present, any repeated elements will be left out. | |
; > (define xs '(a a a b b c d d b b b)) | |
; > (uniq xs) | |
; '(a b c d b) | |
; > (uniq xs #:repeats-only? #t) | |
; '(a b d b) | |
; > (uniq xs #:uniques-only? #t) | |
; '(c) | |
; > (uniq xs #:count #t) | |
; ((a 3) (b 2) (c 1) (d 2) (b 3)) | |
; > (uniq xs #:count #t #:repeats-only? #t) | |
; '((a 3) (b 2) (d 2) (b 3)) | |
; > (uniq xs #:count #t #:uniques-only? #t) | |
; '((c 1)) | |
(require racket/list) | |
(define (uniq xs | |
#:key [=? equal?] | |
#:count [count? #f] | |
#:repeats-only? [repeats? #f] ; only inlude repeats in output | |
#:uniques-only? [unique? #f]) ; no repeats in output | |
(define msg "#:repeats-only? and #:unique-only? are mutually exclusive") | |
(cond | |
[(and repeats? unique?) (error 'unique msg)] | |
[(and repeats? count?) (uniq/count/repeats xs =?)] | |
[(and unique? count?) (uniq/count/uniques xs =?)] | |
[count? (uniq/count xs =?)] | |
[repeats? (uniq/no-count/repeats xs =?)] | |
[unique? (uniq/no-count/uniques xs =?)] | |
[else (uniq/no-count xs =?)])) | |
(define (uniq/no-count xs =?) | |
; filter out repeated elements | |
(cond | |
[(null? xs) '()] | |
[(null? (rest xs)) xs] | |
[else | |
(let loop ([x (first xs)] | |
[xs (rest xs)]) | |
(cond | |
[(null? xs) (list x)] | |
[(=? x (first xs)) (loop x (rest xs))] | |
[else (cons x (loop (first xs) (rest xs)))]))])) | |
(define (uniq/no-count/repeats xs =?) | |
; filter out repeated elements, | |
; only output repeated elements | |
(cond | |
[(null? xs) '()] | |
[(null? (rest xs)) '()] | |
[else | |
(let loop ([x (first xs)] | |
[xs (rest xs)] | |
[repeated? #f]) | |
(cond | |
[(null? xs) (if repeated? (list x) '())] | |
[(=? x (first xs)) (loop x (rest xs) #t)] | |
[else (if repeated? | |
(cons x (loop (first xs) (rest xs) #f)) | |
(loop (first xs) (rest xs) #f))]))])) | |
(define (uniq/no-count/uniques xs =?) | |
; filter out repeated elements, | |
; only output unique elements | |
(cond | |
[(null? xs) '()] | |
[(null? (rest xs)) xs] | |
[else | |
(let loop ([x (first xs)] | |
[xs (rest xs)] | |
[unique? #t]) | |
(cond | |
[(null? xs) (if unique? (list x) '())] | |
[(=? x (first xs)) (loop x (rest xs) #f)] | |
[else (if unique? | |
(cons x (loop (first xs) (rest xs) #t)) | |
(loop (first xs) (rest xs) #t))]))])) | |
(define (uniq/count xs =?) | |
; filter out repeated elements | |
(cond | |
[(null? xs) '()] | |
[(null? (rest xs)) (list (list (first xs) 1))] | |
[else | |
(let loop ([x (first xs)] | |
[xs (rest xs)] | |
[n 1]) | |
(cond | |
[(null? xs) (list (list x n))] | |
[(=? x (first xs)) (loop x (rest xs) (+ n 1))] | |
[else (cons (list x n) | |
(loop (first xs) (rest xs) 1))]))])) | |
(define (uniq/count/repeats xs =?) | |
; filter out repeated elements, | |
; only outputs repeated elements | |
(cond | |
[(null? xs) '()] | |
[(null? (rest xs)) '()] | |
[else | |
(let loop ([x (first xs)] | |
[xs (rest xs)] | |
[n 1]) | |
(cond | |
[(null? xs) (if (= n 1) '() (list (list x n)))] | |
[(=? x (first xs)) (loop x (rest xs) (+ n 1))] | |
[else (if (= n 1) | |
(loop (first xs) (rest xs) 1) | |
(cons (list x n) | |
(loop (first xs) (rest xs) 1)))]))])) | |
(define (uniq/count/uniques xs =?) | |
; filter out repeated elements, | |
; only outputs unique elements | |
(map (λ (x) (list x 1)) | |
(uniq/no-count/uniques xs =?))) | |
(let () | |
(define xs '(1 1 1 2 2 2 3 2 2 55)) | |
"xs" | |
xs | |
"uniq" | |
(uniq xs) | |
"uniq, repeats only" | |
(uniq xs #:repeats-only? #t) | |
"uniq, uniques only" | |
(uniq xs #:uniques-only? #t) | |
"uniq with counts" | |
(uniq xs #:count #t) | |
"uniq with counts, repeats only" | |
(uniq xs #:count #t #:repeats-only? #t) | |
"uniq with counts , uniquess only" | |
(uniq xs #:count #t #:uniques-only? #t)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment