Pregunta

Dada una lista, ¿cómo seleccionaría una nueva lista que contenga una porción de la lista original (dado el desplazamiento y el número de elementos)?

EDITAR:

Buenas sugerencias hasta ahora.¿No hay algo especificado en uno de los SRFI?Esto parece ser algo muy fundamental, por lo que me sorprende que necesite implementarlo en el ámbito de los usuarios.

¿Fue útil?

Solución

El siguiente código hará lo que quieras:

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

Ejemplo:

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

Otros consejos

Extrañamente, slice no está provisto de SRFI-1 pero puedes acortarlo usando SRFI-1 take y drop:

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

Pensé que una de las extensiones que he usado con Scheme, como la biblioteca PLT Scheme o Swindle, tendría esto integrado, pero no parece ser el caso.Ni siquiera está definido en las nuevas bibliotecas R6RS.

Puedes probar esta función:

subsiguiente Inicio de secuencia y final opcional.

El comenzar El parámetro es su compensación.El fin El parámetro se puede convertir fácilmente en la cantidad de elementos a tomar simplemente agregando inicio + número de elementos.

Una pequeña ventaja es que subsiguiente funciona en todas las secuencias, esto incluye no solo listas sino también cadenas y vectores.

Editar:Parece que no todas las implementaciones de lisp tienen subseq, aunque funcionará bien si lo tienes.

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

Aquí está mi implementación de slice que utiliza una llamada de cola adecuada

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

Pruebe algo como esto:

    (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 bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top