Wie nehme ich ein Stück einer Liste (A sublist) in Schema?
Frage
eine Liste gegeben, wie würde ich eine neue Liste auswählen, ein Stück der ursprünglichen Liste enthält (Offset und Anzahl der Elemente gegeben)?
EDIT:
Gute Vorschläge so weit. Ist da nicht etwas in einem der SRFI spezifizierten? Dies scheint eine sehr grundlegende Sache zu sein, so dass ich bin überrascht, dass ich es in benutzer Land implementieren muß.
Lösung
Der folgende Code wird das tun, was Sie wollen:
(define get-n-items
(lambda (lst num)
(if (> num 0)
(cons (car lst) (get-n-items (cdr lst) (- num 1)))
'()))) ;'
(define slice
(lambda (lst start count)
(if (> start 1)
(slice (cdr lst) (- start 1) count)
(get-n-items lst count))))
Beispiel:
> (define l '(2 3 4 5 6 7 8 9)) ;'
()
> l
(2 3 4 5 6 7 8 9)
> (slice l 2 4)
(3 4 5 6)
>
Andere Tipps
Merkwürdigerweise wird slice
nicht mit SRFI-1 Verfügung gestellt, aber Sie kann es kürzer machen, indem SRFI-1 take
und drop
mit:
(define (slice l offset n)
(take (drop l offset) n))
Ich dachte, dass eine der Erweiterungen I Schema verwendet habe, wie die PLT Scheme Bibliothek oder Swindle, hätte dies eingebaut, aber es scheint nicht der Fall zu sein. Es ist nicht einmal in den neuen R6RS Bibliotheken definiert.
Sie können diese Funktion versuchen:
SUBSEQ sequence start & optional Ende
Die starten Parameter wird Ihr gegenüber. Die Ende Parameter lassen sich leicht in die Anzahl der Elemente gedreht werden zu greifen, indem einfach Start + number-of-Elemente.
Ein kleiner Bonus ist, dass SUBSEQ funktioniert auf allen Sequenzen, ist dies nicht nur Listen enthält, sondern auch String und Vektoren.
Edit: Es scheint, dass nicht alle Lisp-Implementierungen haben SUBSEQ, obwohl es die Arbeit machen wird gut, wenn Sie es haben
.(define (sublist list start number)
(cond ((> start 0) (sublist (cdr list) (- start 1) number))
((> number 0) (cons (car list)
(sublist (cdr list) 0 (- number 1))))
(else '())))
Hier ist meine Implementierung von slice
, die einen richtigen Schwanz Aufruf verwendet
(define (slice a b xs (ys null))
(cond ((> a 0) (slice (- a 1) b (cdr xs) ys))
((> b 0) (slice a (- b 1) (cdr xs) (cons (car xs) ys)))
(else (reverse ys))))
(slice 0 3 '(A B C D E F G)) ;=> '(A B C)
(slice 2 4 '(A B C D E F G)) ;=> '(C D E F)
Versuchen Sie etwas wie folgt aus:
(define (slice l offset length)
(if (null? l)
l
(if (> offset 0)
(slice (cdr l) (- offset 1) length)
(if (> length 0)
(cons (car l) (slice (cdr l) 0 (- length 1)))
'()))))