Вопрос по – Как взять фрагмент списка (подсписок) в схеме?

14

Как получить список, как выбрать новый список, содержащий фрагмент исходного списка (с учетом смещения и количества элементов)?

РЕДАКТИРОВАТЬ

Хорошие предложения до сих пор. Разве что-то не указано в одном из SRFI? Кажется, это очень фундаментальная вещь, поэтому я удивлен, что мне нужно реализовать ее в пользовательской среде.

Я просто хочу добавить свою рекомендацию к ответу Натана Сандерса, это определенно лучшее использование SRFI, чем другие материалы. Кроме того, это был бы ответ, который я написал бы. : -) Chris Jester-Young

Ваш Ответ

6   ответов
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)))
                '()))))
8

Следующий код будет делать то, что вы хотите:

(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)
> 
В get-n-items есть опечатка. Остальная часть if-формы нуждается в цитате. Вы можете отредактировать это? troelskn
11

Странно,slice не предоставляется SRFI-1 но вы можете сделать его короче, используя SRFI-1'stake а такжеdrop:

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

Я думал, что одно из расширений, которые я использовал со Scheme, например библиотека PLT Scheme или Swindle, будет иметь эту встроенную функцию, но, похоже, это не так. Это даже не определено в новых библиотеках R6RS.

Вы думаете о срезе Python, который использует offset1, offset2. Для метода смещения по количеству элементов это правильный ответ: «взять 9 элементов, начиная с 3-го»долже даст вам меньше 9, если список исчерпан. (Я лично считаю, что подход Python лучше, но вопрос не в этом.) Nathan Shively-Sanders
Имейте в виду, что с этим ответом вы не можете сделать(slice '(1 2 3 4 5 6 7 8 9 0) 3 9) потому что он выйдет из списка. Вы фактически должны передать ему смещение от начала и длины окончательного списка вместо двух смещений от нуля. Вы также не можете сделать(slice l 3 -4) (что пользователь python мог бы означать «взять все от третьего до четвертого до последнего элемента списка l»). Реальная функция среза была бы немного более сложной. Inaimathi
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 '())))
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)
6

@ Посл начало последовательности и необязательный конец

TheНачалараметр @ - это ваше смещение.конеараметр @ можно легко превратить в число элементов, которые нужно получить, просто добавив start + количество элементов.

Небольшой бонус в том, что @ Посл работает со всеми последовательностями, включая не только списки, но также строки и векторы.

Редактировать: Кажется, что не все реализации lisp имеют subseq, хотя, если он у вас есть, он отлично справится с работой.

Является ли subseq функцией CL? По крайней мере, он не является частью PLT-схемы. troelskn
Гоше есть это: Practical-scheme.net / wiliki / arcxref? @ Посл. не знаю о других. dsm
Weird. Я прочитал об этом Парадигмы ИИ, и он был представлен как часть стандарта. Я думаю, я не уверен, какой из стандартов. : P К сожалению об этом. Josh Gagnon

Похожие вопросы