2016-04-23 11 views
3

Zum Beispiel habe ich eine Liste von "Strings": ("Erste" "zweite" "dritte.").
Und ich muss alle "s" zu "a" ersetzen -> (("Firat") ... etc Ich habe eine sehr schöne Funktion namens Ersatz gefunden, aber es funktioniert nur für eine Sequenz.
Kann ich verwenden Ersatz in mapcar So etwas wie dies:
Wie Argumente für Ersatz in Mapcar angeben?

(mapcar 'substitute #\d #\o '(("test") ("wow") ("waow"))) 
+0

nicht mapcar hier Verwenden Sie scheint eine Schleife besser geeignet. – coredump

Antwort

6

Sie eine LAMBDA um die Funktion wickeln kann:

(mapcar (lambda (string) (substitute #\d #\o string)) '("test" "wow" "waow")) 
;=> ("test" "wdw" "wadw") 

Oder Sie können eine Hilfsfunktion verwenden CURRY genannt (die nicht Teil des Gemeinsamen ist Lisp-Standard, ist aber verfügbar z. B. in Alexandria).

(ql:quickload :alexandria) 
(use-package :alexandria) 
(mapcar (curry #'substitute #\d #\o) '("test" "wow" "waow")) 
;=> ("test" "wdw" "wadw") 

Für mehrere Strings in Unterlisten können Sie verschachtelte mapcar/lambda verwenden:

(mapcar (lambda (sentence) 
      (mapcar (lambda (string) 
        (substitute #\d #\o string)) 
        sentence)) 
     '(("I" "like" "my" "dog.") ("My" "dog" "likes" "me" "too."))) 
;=> (("I" "like" "my" "ddg.") ("My" "ddg" "likes" "me" "tdd.")) 

Die innere LAMBDA zu einem CURRY auch geändert werden könnte:

(mapcar (lambda (sentence) 
      (mapcar (curry #'substitute #\d #\o) sentence)) 
     '(("I" "like" "my" "dog.") ("My" "dog" "likes" "me" "too."))) 

Oder auch:

(mapcar (curry #'mapcar (curry #'substitute #\d #\o)) 
     '(("I" "like" "my" "dog.") ("My" "dog" "likes" "me" "too."))) 
+0

Wow! Ich danke dir sehr! Was es tut: verwendet Lambda (String) zu jedem Element in der Liste, richtig? – Disciples

+0

Lambda erstellt eine anonyme Funktion, die das Mapcar dann auf jedes Element anwendet. Die Funktion nimmt ein einzelnes Argument und verwendet Ersatz dafür. – jkiiski

+0

Hm, okay. Also das ist die Hauptidee, Lambda im Mapcar zu verwenden? Mapcar benötigt nur Funktionen mit 1 Argumenten (das wird ihre Liste sein), und wenn wir eine anonyme Funktion deklarieren, kann sie unsere Liste durchlaufen. – Disciples

4

ich jkiiski bin das Hinzufügen sehr nette Antwort eine letzte Möglichkeit, Argumente zu substitute in diesem Fall zu spezifizieren, obwohl es wahrscheinlich nicht das, was Sie brauchen:

(mapcar #'substitute '(#\x #\x #\x) '(#\a #\b #\c) '("abcd" "abcd" "abcd")) 
;; => ("xbcd" "axcd" "abxd") 

hier für jeden i bis zur untersten Länge eines vergangen Liste, mapcar übergibt das i th-Element der ersten Liste als erstes Argument, das i th-Element des zweiten als zweites Argument und das i th-Element als drittes Argument an substitute. Dies funktioniert, weil mapcar eine oder beliebig viele Listen belegt.

Dies ist nur dann sinnvoll, wenn Sie auf (fast) jedem der Strings unterschiedliche Substitutionen durchführen möchten.

2

Neben einer einfachen Liste einer Rekursion in Erwägung ziehen könnte, den allgemeinen Verschachtelung Fall zu behandeln:

(labels ((my-sub (s) 
      (typecase s 
      (string (substitute #\d #\o s)) 
      (list (mapcar #'my-sub s)) 
      (otherwise s)))) 
    (my-sub '(("I" "like" "my" "dog.") 
     ("My" ("dog" "likes" "me") "too."))))