正如标题所述,我正在尝试编写一个函数,该函数接受一个列表,一个变量和一个元素,然后用该元素替换列表中变量的所有实例。
例如:
(替换'(C或(D或D))'D #f)会返回
'(C或(#f或#f))
现在我所拥有的是:
(define (substitute lst rep new)
(cond ((or (null? lst))
lst)
((eq? (car lst) rep)
(cons new (substitute (cdr lst) rep new)))
(else
(cons (car lst) (substitute (cdr lst) rep new)))))
不会像我的示例那样检查嵌套列表,尽管当嵌套列表不是输入的一部分时它可以很好地工作。
我在将递归放置在哪里时遇到了麻烦-还是将其全部展平然后在以某种方式替换了所有东西之后重建它会更容易吗?
答案 0 :(得分:0)
这是另一种通过match
使用模式匹配的解决方案-
(define (sub l rep new)
(match l
((list (list a ...) b ...) ; nested list
(cons (sub a rep new)
(sub b rep new)))
((list a b ...) ; flat list
(cons (if (eq? a rep) new a)
(sub b rep new)))
(_ ; otherwise
null)))
它是这样的-
(sub '(a b c a b c a b c) 'a 'z)
;; '(z b c z b c z b c)
(sub '(a b c (a b c (a b c))) 'a 'z)
;; '(z b c (z b c (z b c)))
(sub '() 'a 'z)
; '()
答案 1 :(得分:0)
乍看之下,您的问题类似于How to replace an item by another in a list in DrScheme when given paramters are two items and a list?。据我了解,您的问题略有不同,因为您还想替换嵌套列表中的出现项。
为了处理嵌套列表,必须添加一个子句以检查嵌套列表的存在,并通过递归向下嵌套列表来替换该嵌套列表中的所有匹配项:
(define (subst l rep new)
(cond ((null? l)
'())
((list? (car l)) ; Check if it is a nested list.
(cons (subst (car l) rep new) ; Replace occurrences in the nested list.
(subst (cdr l) rep new))) ; Replace occurrences in the rest of the list.
((eq? (car l) rep)
(cons new
(subst (cdr l) rep new)))
(else
(cons (car l)
(subst (cdr l) rep new)))))
示例用法(摘自user633183给出的答案):
(subst '(a b c a b c a b c) 'a 'z)
;; '(z b c z b c z b c)
(subst '(a b c (a b c (a b c))) 'a 'z)
;; '(z b c (z b c (z b c)))
(subst '() 'a 'z)
; '()
答案 2 :(得分:0)
这可以使用映射和递归来完成:
(define (subst lst rep new)
(map (lambda (x)
(if (list? x)
(subst x rep new)
(if (eq? rep x) new x))) lst))
输出:
(subst '(a b c (a b c (a b c))) 'a 'z)
; '(z b c (z b c (z b c)))