リストのn番目の要素を削除する

最初の要素は0番目。

(define delete-nth
  (lambda (lis n)
    (let loop ((c 0) (l lis) (r '()))
      (if (null? l)
          (reverse r)
          (if (= c n)
            (loop (+ c 1) (cdr l) r)
            (loop (+ c 1) (cdr l) (cons (car l) r)))))))

(print (iota 10))
(print (delete-nth (iota 10) 3))
(print '(a b c d e f g h i j))
(print (delete-nth '(a b c d e f g h i j) 3))
^o^ > gosh delete-nth.scm
(0 1 2 3 4 5 6 7 8 9)
(0 1 2 4 5 6 7 8 9)
(a b c d e f g h i j)
(a b c e f g h i j)

ちゃんと 3 と d が消えている。

これを拡張して、「n番目」を複数とれるようにしてみよう。

(define delete-nth
  (lambda (lis . ns)
    (let loop ((c 0) (l lis) (r '()))
      (if (null? l)
          (reverse r)
          (if (include? c ns)
              (loop (+ c 1) (cdr l) r)
              (loop (+ c 1) (cdr l) (cons (car l) r)))))))

(define include?
  (lambda (x lis)
  (cond ((null? lis) #f)
        ((= x (car lis)) #t)
        (else (include? x (cdr lis))))))

(print (iota 10))
(print (delete-nth (iota 10) 3 5 7))
(print '(a b c d e f g h i j))
(print (delete-nth '(a b c d e f g h i j) 3 5 7))
^o^ > gosh delete-nth2.scm
(0 1 2 3 4 5 6 7 8 9)
(0 1 2 4 6 8 9)
(a b c d e f g h i j)
(a b c e g i j)

要素がリストに含まれているか否かを判定する述語が見当たらなかったので、include? を自作した。

「リストのn番目の要素を削除する」への2件のフィードバック

  1. 「要素がリストに含まれているか否かを判定する」にはmemberが使えます。

    1. コメントありがとうございます。
      member は要素がリストに含まれているときにリストを返すので使えないと思ったんですが、述語としても使えるんですね。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください