16

给定一个列表,我将如何选择一个新列表,其中包含原始列表的一部分(给定偏移量和元素数量)?

编辑:

到目前为止的好建议。SRFI 中没有指定内容吗?这似乎是一个非常基本的事情,所以我很惊讶我需要在用户领域实现它。

4

6 回答 6

13

奇怪的是, SRFI-1slice没有提供,但您可以通过使用 SRFI-1来缩短它:takedrop

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

我认为我在 Scheme 中使用的其中一个扩展,如 PLT Scheme 库或 Swindle,会内置此功能,但似乎并非如此。它甚至没有在新的 R6RS 库中定义。

于 2008-09-23T16:02:01.357 回答
9

以下代码将执行您想要的操作:

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

例子:

> (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)
> 
于 2008-09-20T14:08:40.547 回答
6

你可以试试这个功能:

subseq 序列开始和可选结束

start参数是您的偏移量。只需添加 start + number-of-elements 即可轻松将 end 参数转换为要抓取的元素数

一个小的好处是subseq适用于所有序列,这不仅包括列表,还包括字符串和向量。

编辑:似乎并非所有 lisp 实现都有 subseq,但如果你有它,它会很好地完成工作。

于 2008-09-22T18:04:29.510 回答
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 '())))
于 2008-09-20T14:17:36.500 回答
1

这是我slice使用正确尾调用的实现

(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)
于 2016-02-21T09:33:28.310 回答
0

尝试这样的事情:

    (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)))
                '()))))
于 2008-09-20T14:17:39.730 回答