문제
목록이 주어지면 원본 목록의 일부(오프셋 및 요소 수 제공)가 포함된 새 목록을 어떻게 선택합니까?
편집하다:
지금까지 좋은 제안입니다.SRFI 중 하나에 지정된 내용이 없나요?이것은 매우 기본적인 것 같은데, 이걸 사용자 영역에서 구현해야 한다는 사실에 놀랐습니다.
해결책
다음 코드는 원하는 작업을 수행합니다.
(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))))
예:
> (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)
>
다른 팁
이상하게도, slice
제공되지 않습니다 SRFI-1 하지만 SRFI-1을 사용하면 더 짧게 만들 수 있습니다. take
그리고 drop
:
(define (slice l offset n)
(take (drop l offset) n))
나는 PLT Scheme 라이브러리나 Swindle과 같이 Scheme과 함께 사용한 확장 중 하나에 이 기능이 내장되어 있을 것이라고 생각했지만 그렇지 않은 것 같습니다.새로운 R6RS 라이브러리에도 정의되어 있지 않습니다.
다음 기능을 사용해 볼 수 있습니다.
하위 시퀀스 시퀀스 시작 및 선택적 끝
그만큼 시작 매개변수는 오프셋입니다.그만큼 끝 매개변수는 간단히 시작 + 요소 수를 추가하여 가져올 요소 수로 쉽게 전환할 수 있습니다.
작은 보너스는 하위 시퀀스 모든 시퀀스에서 작동하며 여기에는 목록뿐만 아니라 문자열과 벡터도 포함됩니다.
편집하다:모든 lisp 구현에 subseq가 있는 것은 아닌 것 같지만, subseq가 있으면 제대로 작동할 것입니다.
(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 '())))
내 구현은 다음과 같습니다. slice
적절한 tail call을 사용하는 것
(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)
다음과 같이 시도해 보십시오.
(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)))
'()))))
제휴하지 않습니다 StackOverflow