Skip to content

Instantly share code, notes, and snippets.

@gerardpaapu
Created April 26, 2010 12:47
Show Gist options
  • Save gerardpaapu/379285 to your computer and use it in GitHub Desktop.
Save gerardpaapu/379285 to your computer and use it in GitHub Desktop.
#lang scheme
(provide Take)
(define (Take source . patterns)
(if (= (length patterns) 1)
(Take1 source (first patterns))
(map (lambda (source)
(apply Take source (rest patterns)))
(Take1 source (first patterns)))))
(define (Take1 source pattern)
(match pattern
['All source]
['None '()]
[(list index) (list-ref source index)]
[(list first last) (slice source first last)]
[(list first last step) (step-through (slice source first last) step)]
[index (if (negative? index)
(slice source index)
(slice source 1 index))]))
(define (slice ls first [last (length ls)])
(let ([start (index ls (sub1 first))]
[end (index ls last)])
(take (drop ls start)
(- end start))))
(define (index ls n)
;; converts n to an index of ls
;; by wrapping around negative numbers
;; I guess I could modulo the index as well...
(define len (length ls))
(+ n (if (negative? n) len 0)))
(define (step-through ls step)
;; returns the 1st item, then every stepth item
(if (<= (length ls) step)
(list (first ls))
(cons (first ls)
(step-through (drop ls step) step))))
;; examples
;; Take[{a,b,c,d},2] --> {a,b}
(Take '(a b c d) 2) ; -> '(a b)
;; Take[{a,b,c,d},-2] -> {c,d}
(Take '(a b c d) -2) ; -> '(c d)
;; Take[{a,b,c,d},{1,3}] -> {a,b,c}
(Take '(a b c d) '(1 3)) ; -> '(a b c)
;; Take[{a,b,c,d},{1,-1,2}] -> {a,c}
(Take '(a b c d) '(1 -1 2)) ; -> '(a c)
;; Take[{{a,b,c,d},{1,2,3,4},{5,6,7,8}},2,2] -> {{a, b}, {1, 2}}
(Take '((a b c d) (1 2 3 4) (5 6 7 8)) 2 2) ;-> ((a b) (1 2))
;; Take[{{11, 12, 13}, {21, 22, 23}, {31, 32, 33}}, All, 2]
(Take '((11 12 13) (21 22 23) (31 32 33)) 'All 2) ;-> ((11 12) (21 22) (31 32))
;; Take[{{11, 12, 13}, {21, 22, 23}, {31, 32, 33}}, 2, -1]
(Take '((11 12 13) (21 22 23) (31 32 33)) 2 -1) ;-> ((13) (23))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment