bra*_*nto 2 scheme conditional racket
我对于询问这个球拍/方案问题几乎感到尴尬,但有人可以告诉我如何避免在"那里"重复一个函数调用,如果它首先用于确定"这里"的条件吗?(cond [here there])
我想要得到的是相当于Racket/Scheme中的以下C样式代码(注意我只需要调用regex()一次,因为它存储在变量匹配中):
// initialiation code
if (match = regex("start", "startofstring")) {
list->push(match);
}
else {
printf("No matching regex\n");
}
Run Code Online (Sandbox Code Playgroud)
我想要避免的Racket代码如下,因为我必须两次调用regexp-match:
(cond
[(regexp-match #rx"start" "startofstring")
(set! list (cons (regexp-match #rx"start" "startofstring") list)]
[else
(printf "No matching regex\n")])
Run Code Online (Sandbox Code Playgroud)
现在,我可以这样做:
(define match (regexp-match #rx"start" "startofstring"))
(cond
[match
(set! list (cons match list)]
[else
(printf "No matching regex\n")])
Run Code Online (Sandbox Code Playgroud)
但是这种方法意味着如果我有多个条件,我必须定义很多变量(在我的实际代码中,我有多个条件......但是为了上面的代码片段,我只放入一个) .所以它最终看起来像这样丑陋:
(define match1 (regexp-match #rx"start" "startofstring"))
(define match2 (regexp-match #rx"blah" "startofstring"))
....
(define matchn (regexp-match #rx"blahn" "startofstring"))
(cond
[match1
(set! list (cons match1 list)]
[match2
(set! list (cons match2 list)]
....
[matchn
(set! list (cons matchn list)]
[else
(printf "No matching regex\n")])
Run Code Online (Sandbox Code Playgroud)
我想要的是更多的东西:
(cond
[(define match (regexp-match #rx"start" "startofstring"))
(set! list (cons match list)]
[(define match (regexp-match #rx"blah" "startofstring"))
(set! list (cons match list)]
...
[(define match (regexp-match #rx"blahn" "startofstring"))
(set! list (cons match list)]
[else
(printf "No matching regex\n")])
Run Code Online (Sandbox Code Playgroud)
但这显然是语法错误,因为(define .. ..)不能在条件"here"中使用.对不起因为缺乏清晰度......我尽我所能来表达我的意思.我知道这非常简单,但我不能完全围绕它(我没有使用除c风格语言之外的语言).
正确的解决方案是使用cond的=>形式:
(cond ((regexp-match #rx"start" "startofstring")
=> (lambda (match)
(set! lst (cons match lst))))
...)
Run Code Online (Sandbox Code Playgroud)
(请注意,我重命名了您的list变量,lst以避免影响内置list过程.)
如果您有多个模式,并且对多个模式执行相同的操作,则应将公共代码提取到单独的过程中:
(define (push! match)
(set! lst (cons match lst)))
(cond ((regexp-match #rx"start" str) => push!)
((regexp-match #rx"blah" str) => push!)
...)
Run Code Online (Sandbox Code Playgroud)
虽然上面的工作,我想建议你不要使用set!,因为它不是很实用.从循环构建列表的标准Scheme方法是使用命名let,如下所示:
(let loop ((result '())
(strs strs))
(define (next match)
(loop (cons match result) (cdr strs)))
(if (null? strs)
result
(let ((str (car strs)))
(cond ((regexp-match #rx"start" str) => next)
...)))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
305 次 |
| 最近记录: |