lisp - resueltos - ¿Cómo tomo una porción de una lista(una sublista) en el esquema?
setq lisp (6)
Dada una lista, ¿cómo seleccionaría una nueva lista, que contiene una porción de la lista original (Desplazamiento dado y número de elementos)?
EDITAR:
Buenas sugerencias hasta ahora. ¿No hay algo especificado en uno de los SRFI? Esto parece ser algo muy fundamental, así que estoy sorprendido de que necesito implementarlo en user-land.
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)
>
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)))
''()))))
(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 ''())))
Extrañamente, slice
no está provisto con SRFI-1, pero puedes hacerlo más corto usando SRIT-1''s take
and 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 incorporado, pero no parece ser el caso. Ni siquiera está definido en las nuevas bibliotecas R6RS.
Puedes probar esta función:
subseq secuencia inicio y final opcional
El parámetro de inicio es su desplazamiento. El parámetro final se puede convertir fácilmente en la cantidad de elementos a capturar simplemente agregando start + number-of-elements.
Una pequeña ventaja es que subseq 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 hará bien el trabajo si lo tiene.
Aquí está mi implementación de slice
que usa una llamada correcta
(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)