Pergunta

Dada uma lista, como eu selecionar uma nova lista, que contém uma fatia da lista original (dado offset e número de elementos)?

EDIT:

Boas sugestões até agora. Não há algo especificado em um dos de SRFI? Esta parece ser uma coisa muito fundamental, por isso estou surpreso que eu preciso para implementá-lo em user-terra.

Foi útil?

Solução

O código a seguir irá fazer o que quiser:

(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))))

Exemplo:

> (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)
> 

Outras dicas

Estranhamente, slice não é fornecido com SRFI-1 mas você pode torná-lo mais curto usando de SRFI-1 take e drop :

(define (slice l offset n)
  (take (drop l offset) n))

Eu pensei que uma das extensões que eu usei com Scheme, como a biblioteca PLT Scheme ou Swindle, teria este built-in, mas não parece ser o caso. Não é sequer definido nas novas bibliotecas R6RS.

Você pode tentar esta função:

subseq sequência inicial e final opcional

O Iniciar parâmetro é o seu deslocamento. O final parâmetro pode ser facilmente transformado no número de elementos de agarrar simplesmente adicionando começo + número-of-elementos.

Um pequeno bônus é que subseq funciona em todas as seqüências, o que inclui não só as listas, mas também cordas e vetores.

Edit:. Parece que nem todas as implementações Lisp tem subseq, embora ele vai fazer o trabalho muito bem se tiver

(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 '())))

Aqui está minha implementação do slice que usa uma chamada cauda adequada

(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)

Tente algo parecido com isto:

    (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)))
                '()))))
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top