5

基本的に、 map を使用して、次のようなリストで選択を行いたいと思います

(define tbl '(a b c d))
(map (lambda (item 'c) (if (eq? item 'c) item (...what in else?) )))

私が望む結果は

'(c)

else 部分を空のままにしてみましたが、else 部分が必要であると不平を言います。私は試した

(display "foo") 

as else part と got

(#<void> #<void> c #<void>)

それは近いです。

map を使用して '(c) を取得する方法はありますか? 私は再帰的な方法を知っていますが、 map も同様にできるかどうか疑問に思っています。'(c) でない場合は、少なくとも (# # c #) ですが、void 型の戻り値を実現するためにディスプレイ ハックを使用しません。


4

3 に答える 3

12

出力リストの要素が入力リストよりも少ない可能性があるため、-filterではなくを使用します。によって返される値はmapすべてそこにあります。これは、関心のない要素であっても、出力リストに常に結果が含まれるためです。#<void>displaymap

(define tbl '(a b c d))

(filter (lambda (item) (eq? item 'c)) tbl)
=> '(c)

同様に、少し短く:

(filter (curry eq? 'c) tbl)
=> '(c)

map要素を破棄せずに、入力リスト内の各要素に対して何かをしたい場合に使用されます。一方、入力リスト内の要素の一部filterを選択するために使用されます。これは、特定の述語に対して評価されるものであり、ほとんどのスキーム インタープリターで使用できます。使用できない場合は、参照実装をインポートまたは使用できます。#tfilterSRFI-1

のみ'(c)を使用して取得する方法はありません( plusやなどを使用してハッキングできますが、それはアイデアではありませんね?); 何らかの理由でのみ使用する必要があり、プレースホルダーを含むリストを返すことを気にしない場合は、いくつかの代替手段があります。 mapmapapplyremove*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>)

ちょっとしたハッキン​​グの時間です。mapplusを使用すると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)
于 2013-07-16T15:31:13.783 に答える