スキームでリスト (サブリスト) のスライスを取得するにはどうすればよいですか?
質問
リストが与えられた場合、元のリストのスライス (指定されたオフセットと要素数) を含む新しいリストを選択するにはどうすればよいでしょうか?
編集:
これまでのところ良い提案があります。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)
>
他のヒント
不思議なことに、 slice
は提供されていません SRFI-1 ただし、SRFI-1 を使用すると短くすることができます。 take
そして drop
:
(define (slice l offset n)
(take (drop l offset) n))
PLT Scheme ライブラリや Swindle など、Scheme で使用した拡張機能の 1 つにはこれが組み込まれているのではないかと思いましたが、そうではないようです。新しい R6RS ライブラリでも定義されていません。
この機能を試すことができます:
後続 シーケンスの開始(&オプション)終了
の 始める パラメータはオフセットです。の 終わり パラメータは、start + 要素数を加算するだけで、取得する要素の数に簡単に変換できます。
ちょっとしたボーナスは、 後続 すべてのシーケンスに対して機能します。これにはリストだけでなく文字列やベクトルも含まれます。
編集:すべての Lisp 実装に subseq があるわけではないようですが、subseq がある場合は問題なく機能します。
(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 '())))
これが私の実装です 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)
次のようなことを試してください。
(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)))
'()))))
所属していません StackOverflow