你想用filter
,不map
- 因爲輸出列表將可能具有比輸入列表中少的元素。通過display
返回所有這些#<void>
值是有,因爲map
總是包含在輸出列表中的結果,甚至爲那些我們不感興趣的元素
(define tbl '(a b c d))
(filter (lambda (item) (eq? item 'c)) tbl)
=> '(c)
等價的,又有點短。
(filter (curry eq? 'c) tbl)
=> '(c)
map
用於您希望對輸入列表中的每個元素執行某些操作而不丟棄元素。另一方面,filter
用於在輸入列表中選擇一些的元素,對於給定的謂詞則評估爲#t
,filter
在大多數Scheme解釋器中可用,如果它不可用,則可以導入SRFI-1
或使用reference implementation。
有沒有辦法使用獲得'(c)
只map
(它可以使用map
加apply
或remove*
等,被黑客入侵,但是這不是想法,是嗎?);如果由於某種原因,你必須只使用map
,不介意與返回佔位符列表,這裏有幾個選擇:
(map (lambda (item) (if (eq? item 'c) item '%)) tbl) ; placeholder in else part
=> '(% % c %)
(map (lambda (item) (when (eq? item 'c) item)) tbl) ; when has implicit #<void>
=> '(#<void> #<void> C#<void>)
時間一點點的黑客。使用map
加apply
(如@WillNess的回答解釋),這在任何RxRS解釋工作的優勢,是目前最便攜的解決方案,因爲它使用了標準程序:
(apply append (map (lambda (item) (if (eq? item 'c) (list item) '())) tbl))
=> '(c)
使用map
加remove*
:
(remove* (list (void)) (map (lambda (item) (when (eq? item 'c) item)) tbl))
=> '(c)
對於改變,沒有map
溶液 - 使用foldr
代替:
(foldr (lambda (item a) (append (if (eq? item 'c) (list item) '()) a)) '() tbl)
=> '(c)
當然,你總是可以實現只用標準程序你的filter
自己的版本,這也將是可跨所有RxRS解釋:
(define (filter pred? lst)
(cond ((null? lst)
'())
((not (pred? (car lst)))
(filter pred? (cdr lst)))
(else
(cons (car lst)
(filter pred? (cdr lst))))))
(filter (lambda (item) (eq? item 'c)) tbl)
=> '(c)
順便說一句:作爲參數傳遞給'map'了'lambda'必須接收_single_參數,你傳遞兩個將無法工作:'(項目「C )' –
你在用什麼解釋器?我的猜測是Racket,但請確認 –
@ÓscarLópez,是的,它是Racket,但我希望解決方案可以是普遍的 –