代码之家  ›  专栏  ›  技术社区  ›  troelskn

我如何在Scheme中从一个列表(子列表)中获取一个片段?

  •  14
  • troelskn  · 技术社区  · 16 年前

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

    编辑:

    到目前为止还不错的建议。其中一个SRFI中没有指定的内容吗?这似乎是一个非常基本的东西,所以我很惊讶我需要在用户土地上实现它。

    6 回复  |  直到 8 年前
        1
  •  8
  •   dsm    16 年前

    以下代码将按您的需要执行:

    (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)
    > 
    
        2
  •  11
  •   Nathan Shively-Sanders    16 年前

    奇怪的是, slice 不提供 SRFI-1 但是你可以通过使用SRFI-1来缩短它 take and drop :

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

    我以为我在Scheme中使用的一个扩展,比如PLT方案库或诈骗,会有这个内置的,但似乎不是这样。在新的R6RS库中甚至没有定义它。

        3
  •  5
  •   Josh Gagnon Steinar    16 年前

    您可以尝试此功能:

    亚赛克 序列开始和可选结束

    这个 开始 参数是您的偏移量。这个 结束 只需添加start+元素个数,就可以轻松地将参数转换为要获取的元素个数。

    一个小的奖金是 亚赛克 适用于所有序列,这不仅包括列表,还包括字符串和向量。

    编辑:似乎并不是所有的Lisp实现都有subsq,但是如果您有它的话,它可以做得很好。

        4
  •  1
  •   Matthias Benkard    16 年前
    (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 '())))
    
        5
  •  1
  •   Mulan    8 年前

    这是我的实现 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)
    
        6
  •  0
  •   Martin Cote    16 年前

    尝试如下操作:

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