我正在编写一个从嵌套列表中删除字符串的过程。例子:
(define fubar '(("a" -1 7) (2 "c") ("d") (-2)))
(remove strings fubar) should return '((-1 7) (2) () (-2)).
因为列表是嵌套的,所以您不能简单地cdr
向下列表,因此您需要一种方法来按顺序单独挑选每个列表的每个元素并检查是否有字符串。关于如何去做的任何想法?
我正在编写一个从嵌套列表中删除字符串的过程。例子:
(define fubar '(("a" -1 7) (2 "c") ("d") (-2)))
(remove strings fubar) should return '((-1 7) (2) () (-2)).
因为列表是嵌套的,所以您不能简单地cdr
向下列表,因此您需要一种方法来按顺序单独挑选每个列表的每个元素并检查是否有字符串。关于如何去做的任何想法?
遍历列表列表的解决方案遵循众所周知的解决方案模板,我将给出一般结构,因此您可以填空:如果您自己找到解决方案会更好方法!
(define (remove-strings lst)
(cond (<???> <???>) ; if the list is empty, return the empty list
((not (pair? <???>)) ; if the current element is not a list
(if (string? <???>) ; if the current element is a string
(remove-strings <???>) ; simply advance recursion over cdr (*)
(cons <???> ; else keep the current element
(remove-strings <???>)))) ; advance recursion over cdr
(else ; otherwise it's a list of lists
(cons (remove-strings <???>) ; advance recursion over car
(remove-strings <???>))))) ; advance recursion over cdr
请注意,在(*)
我们“删除”所有找到的字符串时,只需在构建新列表的过程中忽略它们,在下一行中,如果它不是字符串,那么我们在构建输出列表时保留该元素。以上将适用于任意嵌套列表。
这是一个让您入门的框架,树递归的技巧是在汽车和 cdr 上递归,如果汽车本身就是一个列表
(define (remove-strings fubar)
(cond ((null? fubar) ...)
((pair? (car fubar))
(cons (... (car fubar)) (... (cdr fubar))
(else ...)))