How do I take a slice of a list (A sublist) in scheme?

后端 未结 6 2056
悲&欢浪女
悲&欢浪女 2020-12-31 07:09

Given a list, how would I select a new list, containing a slice of the original list (Given offset and number of elements) ?

EDIT:

Good suggestions so far. I

相关标签:
6条回答
  • 2020-12-31 07:34

    Strangely, slice is not provided with SRFI-1 but you can make it shorter by using SRFI-1's take and drop:

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

    I thought that one of the extensions I've used with Scheme, like the PLT Scheme library or Swindle, would have this built-in, but it doesn't seem to be the case. It's not even defined in the new R6RS libraries.

    0 讨论(0)
  • 2020-12-31 07:35

    Try something like this:

        (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)))
                    '()))))
    
    0 讨论(0)
  • 2020-12-31 07:45

    The following code will do what you want:

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

    Example:

    > (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)
    > 
    
    0 讨论(0)
  • 2020-12-31 07:47
    (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 '())))
    
    0 讨论(0)
  • 2020-12-31 07:49

    You can try this function:

    subseq sequence start &optional end

    The start parameter is your offset. The end parameter can be easily turned into the number of elements to grab by simply adding start + number-of-elements.

    A small bonus is that subseq works on all sequences, this includes not only lists but also string and vectors.

    Edit: It seems that not all lisp implementations have subseq, though it will do the job just fine if you have it.

    0 讨论(0)
  • 2020-12-31 07:50

    Here's my implementation of slice that uses a proper 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)
    
    0 讨论(0)
提交回复
热议问题