Chcesz użyć filter
, nie map
- ponieważ lista wyjściowa będzie potencjalnie mają mniej elementów niż listy wejściowej. Wszystkie te #<void>
Wartości zwracane przez display
istnieją ponieważ map
będzie zawsze zawierać wynik na liście wyjściowej, nawet dla tych elementów nie jesteśmy zainteresowani
(define tbl '(a b c d))
(filter (lambda (item) (eq? item 'c)) tbl)
=> '(c)
równoważnie i nieco krótsze.
(filter (curry eq? 'c) tbl)
=> '(c)
map
jest używany, gdy chcesz coś zrobić dla każdego elementu na liście wejściowej, bez odrzucania elementów. Z drugiej strony, filter
jest używany do wybierania niektórych elementów na liście wejściowej, tych, które oceniają na #t
dla danego predykatu, a filter
jest dostępny w większości tłumaczy schematów, jeśli nie jest dostępny, można zaimportować SRFI-1
lub użyć reference implementation.
Nie ma sposobu, aby uzyskać '(c)
użyciu tylkomap
(może to być posiekany użyciu map
plusa apply
lub remove*
itd, ale nie jest to pomysł, prawda?); jeśli z jakiegoś powodu trzeba użytku map
i nie przeszkadza powrocie listę zastępcze, oto kilka alternatyw:
(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>)
Czas na mały hacking.Korzystanie map
powiększonej apply
(jak wyjaśniono w odpowiedzi @WillNess'), to ma tę zaletę, że działa w każdej tłumacza RXR i jest najbardziej przenośnym rozwiązaniem, ponieważ wykorzystuje standardowe procedury:
(apply append (map (lambda (item) (if (eq? item 'c) (list item) '())) tbl))
=> '(c)
Korzystanie map
plusa remove*
:
(remove* (list (void)) (map (lambda (item) (when (eq? item 'c) item)) tbl))
=> '(c)
Dla odmiany, rozwiązanie bez map
- używając foldr
zamiast:
(foldr (lambda (item a) (append (if (eq? item 'c) (list item) '()) a)) '() tbl)
=> '(c)
Oczywiście, zawsze można zaimplementować własną wersję filter
używając tylko standardowe procedury, będzie to również przenośny we wszystkich RXR tłumaczy:
(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)
Przez sposób: 'lambda' przekazany jako parametr' map' musi otrzymać parametr _single_, jesteś przejazdem dwa i że nie będzie działać: '(pozycja„c) ' –
Jakiego tłumacza używasz? Domyślam się, że rakieta, ale proszę, potwierdź to. –
@ Óscar López, tak, to rakieta, ale mam nadzieję, że rozwiązanie może być ogólne. –