我一般对球拍和方案语言都不熟悉,我很难实现自己的想法。
基本上,我有一个函数列表(叫它List f
)和一个字符串列表(叫它List s
)。我需要为f中的每个函数执行该函数,并将值存储在另一个列表中(让调用为List done
)。
例如:假设我有List A = (f1 f2)
和List B = (a b c)
,我将执行:
f1 a
f1 b
f1 c
f2 a
f2 b
f2 c
他们都将其值附加到List done
我也不能在球拍中使用任何形式的set
。
我了解这是应该如何工作的,并且可以轻松地用C或Java编写代码,但是方案给我带来了麻烦。
答案 0 :(得分:3)
在Racket中,有许多内置过程可轻松解决涉及操纵列表的问题。对于您的示例,您正在寻找for*/list
:
(define A (list string-upcase string-downcase))
(define B (list "Aa" "Bb" "Cc"))
(define done
(for*/list ([f A] [s B])
(f s)))
遍历A
中的所有元素,依次将每个元素分配给变量f
。并且在嵌套循环中,它还会迭代B
中的所有元素,依次将每个元素分配给变量s
。在循环的主体中,它将每个f
应用于所有s
,并在输出列表中收集所有内容。现在done
包含期望值:
done
=> '("AA" "BB" "CC" "aa" "bb" "cc")
如果我们要使用递归手动完成此操作,则将需要更多工作。可能的实现方式是使一个过程执行“外部”循环,这将调用另一个过程进行“内部”循环。第三个过程将启动递归并合并结果:
(define (outer-loop funcs params)
(if (null? funcs)
'()
(cons (inner-loop (car funcs) params)
(outer-loop (cdr funcs) params))))
(define (inner-loop f params)
(if (null? params)
'()
(cons (f (car params))
(inner-loop f (cdr params)))))
(define (apply-funcs funcs params)
(apply append ; required to "flatten" the list of lists
(outer-loop funcs params)))
我们将像这样使用它:
(define done (apply-funcs A B))
首先,您应该学习如何通过实现自己的循环来手动解决列表问题。一旦确信自己了解自己在做什么,就花一些时间来学习现有的list procedures和iterations and comprehensions,这是在现实生活中使用该语言的惯用方式。