Come posso prendere una fetta di un elenco (un elenco secondario) nello schema?

StackOverflow https://stackoverflow.com/questions/108169

  •  01-07-2019
  •  | 
  •  

Domanda

Dato un elenco, come selezionerei un nuovo elenco, contenente una porzione dell'elenco originale (dato offset e numero di elementi)?

EDIT:

Buoni suggerimenti finora. Non c'è qualcosa di specificato in uno degli SRFI? Sembra essere una cosa fondamentale, quindi sono sorpreso di doverlo implementare in user-land.

È stato utile?

Soluzione

Il seguente codice farà quello che vuoi:

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

Esempio:

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

Altri suggerimenti

Stranamente, slice non è fornito con SRFI- 1 ma puoi accorciarlo usando di SRFI-1 code> take e drop :

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

Ho pensato che una delle estensioni che ho usato con Scheme, come la libreria Scheme PLT o Swindle, avrebbe questo built-in, ma non sembra essere il caso. Non è nemmeno definito nelle nuove librerie R6RS.

Puoi provare questa funzione:

  

subseq inizio sequenza & fine opzionale

Il parametro start è il tuo offset. Il parametro end può essere facilmente trasformato nel numero di elementi da acquisire semplicemente aggiungendo start + numero di elementi.

Un piccolo vantaggio è che subseq funziona su tutte le sequenze, questo include non solo elenchi ma anche stringhe e vettori.

Modifica: sembra che non tutte le implementazioni di lisp abbiano subseq, anche se funzionerà bene se ce l'hai.

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

Ecco la mia implementazione di slice che utilizza una corretta chiamata di coda

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

Prova qualcosa del genere:

    (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)))
                '()))))
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top