Function SUBST, SUBST-IF, SUBST-IF-NOT, NSUBST, NSUBST-IF, NSUBST-IF-NOT

UP


Function SUBST, SUBST-IF, SUBST-IF-NOT, NSUBST, NSUBST-IF, NSUBST-IF-NOT

Function SUBST, SUBST-IF, SUBST-IF-NOT, NSUBST, NSUBST-IF, NSUBST-IF-NOT

構文

subst new old tree &key key test test-not => new-tree
subst-if new predicate tree &key key => new-tree
subst-if-not new predicate tree &key key => new-tree
nsubst new old tree &key key test test-not => new-tree
nsubst-if new predicate tree &key key => new-tree
nsubst-if-not new predicate tree &key key => new-tree

引数と戻り値

new - オブジェクト
old - オブジェクト
predicate - 関数名のシンボルか、 1つの引数をとりgeneralized-booleanを返却する関数
tree - ツリー
test - 2つの引数を取りgeneralized-booleanを返却する関数の指定子
test-not - 2つの引数を取りgeneralized-booleanを返却する関数の指定子
key - 1つの引数を取りgeneralized-booleanを返却する関数の指定子、 またはnil
new-tree - ツリー

定義

subst, subst-if, subst-if-notは、 treeの置換操作を行います。 各関数はtreeに対してtestを満たすような特定のold要素か、 あるいは部分式を満たすものを検索します。

nsubst, nsubst-if, nsubst-if-notはそれぞれ subst, subst-if, subst-if-notと似ていますが、 元のtreeを修正するところが違っています。

substtreeのコピーを作成し、 全てのサブツリー、葉、親のcar部、cdr部、すべてに対して oldtestが満たされる部分をnewに置換します。

nsubstは、substの破壊的バージョンです。 treeのリスト構造は、それぞれのtreeの葉に対して、 oldtestが満たされる葉の部分を newで破壊的に置換することによって変更されます

subst, subst-if, subst-if-notは、 もし関数が成功すると、 指定された要素のそれぞれの出現をnew要素で置き換えられたものか、 あるいは部分式で置き換えられたものの新たなコピーが返却されます。 もし変更が生じなかったときは、元のtreeが返却されるかもしれません。 元のtreeが変更されないとしても、 返却値のツリーは元のツリーと ストレージを共有しているかもしれません。

nsubst, nsubst-if, nsubst-if-notは、 元のtreeを修正し返却します。 しかし関数の結果は、treeeqで等しくないかもしれません。

例文

(setq tree1 '(1 (1 2) (1 2 3) (1 2 3 4))) =>  (1 (1 2) (1 2 3) (1 2 3 4))
(subst "two" 2 tree1) =>  (1 (1 "two") (1 "two" 3) (1 "two" 3 4))
(subst "five" 5 tree1) =>  (1 (1 2) (1 2 3) (1 2 3 4))
(eq tree1 (subst "five" 5 tree1)) =>  implementation-dependent
(subst 'tempest 'hurricane
       '(shakespeare wrote (the hurricane)))
=>  (SHAKESPEARE WROTE (THE TEMPEST))
(subst 'foo 'nil '(shakespeare wrote (twelfth night)))
=>  (SHAKESPEARE WROTE (TWELFTH NIGHT . FOO) . FOO)
(subst '(a . cons) '(old . pair)
       '((old . spice) ((old . shoes) old . pair) (old . pair))
       :test #'equal)
=>  ((OLD . SPICE) ((OLD . SHOES) A . CONS) (A . CONS))

(subst-if 5 #'listp tree1) =>  5
(subst-if-not '(x) #'consp tree1) 
=>  (1 X)

tree1 =>  (1 (1 2) (1 2 3) (1 2 3 4))
(nsubst 'x 3 tree1 :key #'(lambda (y) (and (listp y) (third y)))) 
=>  (1 (1 2) X X)
tree1 =>  (1 (1 2) X X)

副作用

nsubst, nsubst-if, nsubst-if-notは、 treeのツリー構造を変更するかもしれません。

影響

なし。

例外

なし。

参考

substitute, nsubstitute, 3.2.1. コンパイラーの用語, 3.6. 横断の規則と副作用

備考

:test-notパラメーターは非推奨です。

関数subst-if-notnsubst-if-notは非推奨です。

substは一例として次のように定義できます。

(defun subst (old new tree &rest x &key test test-not key)
  (cond ((satisfies-the-test old tree :test test
                             :test-not test-not :key key)
         new)
        ((atom tree) tree)
        (t (let ((a (apply #'subst old new (car tree) x))
                 (d (apply #'subst old new (cdr tree) x)))
             (if (and (eql a (car tree))
                      (eql d (cdr tree)))
                 tree
                 (cons a d))))))

TOP, Github