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を修正するところが違っています。
substはtreeのコピーを作成し、 全てのサブツリー、葉、親のcar部、cdr部、すべてに対して oldとtestが満たされる部分をnewに置換します。
nsubstは、substの破壊的バージョンです。 treeのリスト構造は、それぞれのtreeの葉に対して、 oldとtestが満たされる葉の部分を newで破壊的に置換することによって変更されます
subst, subst-if, subst-if-notは、 もし関数が成功すると、 指定された要素のそれぞれの出現をnew要素で置き換えられたものか、 あるいは部分式で置き換えられたものの新たなコピーが返却されます。 もし変更が生じなかったときは、元のtreeが返却されるかもしれません。 元のtreeが変更されないとしても、 返却値のツリーは元のツリーと ストレージを共有しているかもしれません。
nsubst, nsubst-if, nsubst-if-notは、 元のtreeを修正し返却します。 しかし関数の結果は、treeとeqで等しくないかもしれません。
(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-notとnsubst-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))))))