如何在方案中获取列表的一部分(子列表)?
时间:2020-03-06 14:29:03 来源:igfitidea点击:
给定一个列表,我如何选择一个包含原始列表切片的新列表(给出偏移量和元素数量)?
编辑:
到目前为止,很好的建议。 SRFI之一中没有指定任何内容吗?这似乎是一件非常基本的事情,所以令我惊讶的是我需要在用户领域实现它。
解决方案
以下代码将执行我们想要的操作:
(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) >
(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 '())))
尝试这样的事情:
(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))) '()))))
我们可以尝试以下功能:
subseq sequence start &optional end
起始参数是偏移量。只需添加start +元素数,即可将end参数轻松转换为要获取的元素数。
一个小好处是subseq可在所有序列上使用,不仅包括列表,而且包括字符串和向量。
编辑:似乎不是所有的Lisp实现都具有subseq,尽管如果有的话,它将做的很好。
奇怪的是,'slice'并未随SRFI-1一起提供,但是我们可以通过使用SRFI-1的take
和drop
来使其更短:
(define (slice l offset n) (take (drop l offset) n))
我认为我用于Scheme的扩展之一(例如PLT Scheme库或者Swindle)将具有此内置功能,但事实并非如此。在新的R6RS库中甚至没有定义它。