| |
| Gut zu wissen: Hilfreiche Tipps und Tricks aus der Praxis prägnant, und auf den Punkt gebracht für Autodesk Produkte |
| |
| PNY präsentiert die neue NVIDIA RTX A400 und die A1000 Grafikkarte, eine Pressemitteilung
|
Autor
|
Thema: Änfängerfrage zu mapcar, lambda (1665 mal gelesen)
|
molo Mitglied Dipl. Ing. Versorgungstechnik
Beiträge: 384 Registriert: 16.07.2002 Windows XP, AutoCAD 2008
|
erstellt am: 29. Okt. 2008 12:47 <-- editieren / zitieren --> Unities abgeben:
Moin Moin, ich habe mit viel Mühe eine kleine Lisp hinbekommen die mir einen Text mit einer Zeichenkette auf eine bestimmte Farbe setzt. ---------------------------------------------------------- ;; Morten Lorenz ;; Test einen Text mit einer Zeichenkette eine Farbe zuzuweisen (defun mltest (string / as) (setq as (ssget "x" (list (cons 0 "TEXT") (cons 1 string)))) (if as (command "._change" as "" "Eigenschaften" "_color" "2" "")) (setq as nil) (princ) ) ------------------------------------------------------------- Wenn ich (mltest "F90") eingebe, werden alle Texte die F90 lauten auf Gelb gesetzt. Jetzt dachte ich mit folgender Lisp eine Reihe von Zeichenketten gleichzeitig auf eine Farbe setzen zu können. --------------------------------------------- (defun c:mlt04 ( / zeichenkette) (setq zeichenkette '("F90" "RS")) (mapcar '(lambda (string / as) ((setq as (ssget "x" (list (cons 0 "TEXT") (cons 1 string)))) (if as (command "._change" as "" "Eigenschaften" "_color" "4" "")) (setq as nil) (princ) ) ) zeichenkette ) ) -------------------------------------------------------- Hier habe ich meiner Meinung nach, die Lisp von vorher zu einer Lambdafunktion gemacht, welche ich durch mapcar mit der Liste Zeichenkette durcharbeite. Leider bekomme ich dadurch eine fehlerhafte Funktion. Habe ich die ganze Sache völlig falsch verstanden, oder nur einen kleinen Fehler gemacht. Wäre super, wenn jemand sich für so einen Greenhornfrage erbarmen könnte. Morten ------------------ Schöne Grüsse, Morten Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
CADmium Moderator Maschinenbaukonstrukteur
Beiträge: 13527 Registriert: 30.11.2003 .
|
erstellt am: 29. Okt. 2008 12:59 <-- editieren / zitieren --> Unities abgeben: Nur für molo
2 Möglichkeiten .. 1. Einen Auswahlsatz bilden mit mehreren möglichen Textstrings .. also einfach dein 1. Lisp aufrufen mit (mltest "F90,F80,F70") oder 2. oder so (defun mltest (stringliste) (mapcar '(lambda(STRING / AS) (if(setq as (ssget "x" (list (cons 0 "TEXT") (cons 1 string)))) (command "._change" as "" "Eigenschaften" "_color" "2" "") ) ) STRINGLISTE ) (princ) ) --> aufruf mit (mltest '("F90" "F80" "F70")) ------------------ - Thomas - "Bei 99% aller Probleme ist die umfassende Beschreibung des Problems bereits mehr als die Hälfte der Lösung desselben." Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Dorfy Mitglied Double-Dipl.-Ing. Bleistiftanspitzer
Beiträge: 900 Registriert: 21.07.2006 AutoCad2007, ProE, HiCad
|
erstellt am: 29. Okt. 2008 13:38 <-- editieren / zitieren --> Unities abgeben: Nur für molo
hi, für einfachere Sache wie diese sollt auch ein foreach ausreichen (defun mltest (stringliste /) (foreach string stringliste (if(setq as (ssget "x" (list (cons 0 "TEXT") (cons 1 string)))) (command "._change" as "" "Eigenschaften" "_color" "2" "") ) ) (princ) ) --> Aufruf: (mltest '("F90" "F80" "F70")) mfg heiko Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
molo Mitglied Dipl. Ing. Versorgungstechnik
Beiträge: 384 Registriert: 16.07.2002 Windows XP, AutoCAD 2008
|
erstellt am: 29. Okt. 2008 18:16 <-- editieren / zitieren --> Unities abgeben:
Danke für die Hilfe! also war ich doch nicht so ganz auf dem Holzweg :-) Wenn ich es jetzt richtig nachvollzogen habe, war mein Fehler, dass ich den Part (setq as (ssget "x" (list (cons 0 "TEXT") (cons 1 string)))) (if as (command "._change" as "" "Eigenschaften" "_color" "4" "")) (setq as nil) (princ) noch mal extra in ein extra Klammerpaar gesetzt habe. Dadurch fing die lambda-Funktion nicht richtig an. Zusätzlich waren die weiteren Tips natürlich auch sehr hilfreich für mich! Und morgen versuche ich sowohl alle Texte und MTexte die eine Zeichenkette enthalten umzuwandeln ;-) ------------------ Schöne Grüsse, Morten Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Brischke Moderator CAD on demand GmbH
Beiträge: 4187 Registriert: 17.05.2001 AutoCAD 20XX, defun-tools (d-tools.eu)
|
erstellt am: 30. Okt. 2008 03:53 <-- editieren / zitieren --> Unities abgeben: Nur für molo
Zitat: Original erstellt von molo: ...Und morgen versuche ich sowohl alle Texte und MTexte die eine Zeichenkette enthalten umzuwandeln ;-) ...
Dabei wünsche ich dir viel Erfolg und gebe dir gerne noch einen Hinweis: Dein Code wird um Genau ein Zeichen 'länger'. Dieses Zeichen wird das '*' sein. Wohin solltest du wissen, wenn du weißt, dass die Filterliste zur Bildung von Auswahlsätzen eben auch mit Platzhaltern gefüttert werden kann (Siehe in der Hilfe unter wcmatch und Wildcards). ... und nun warte ich mal auf das Ergebnis. Grüße! Holger ------------------ Holger Brischke CAD on demand GmbH Individuelle Lösungen von Heute auf Morgen. Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
molo Mitglied Dipl. Ing. Versorgungstechnik
Beiträge: 384 Registriert: 16.07.2002 Windows XP, AutoCAD 2008
|
erstellt am: 30. Okt. 2008 06:17 <-- editieren / zitieren --> Unities abgeben:
OK du warst also früh Wach oder lange auf ;-) Ich war früh wach und habe schon bevor ich das gelesen habe rumprobiert. Ich habe eine Lambda-Funktion in die andere gesetzt. Ich versuche es aber auch noch mit der Einzeichenerweiterung an. Vielen Dank nochmal. Morten ------------------ Schöne Grüsse, Morten Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
molo Mitglied Dipl. Ing. Versorgungstechnik
Beiträge: 384 Registriert: 16.07.2002 Windows XP, AutoCAD 2008
|
erstellt am: 30. Okt. 2008 06:19 <-- editieren / zitieren --> Unities abgeben:
Da habe ich zu schnell "Antwort Speichern" gedrückt. Hier ist meine Funktion in Funktion. (defun mlt08 (stringliste / textliste) ;(setq stringliste '("qwe" "asd")) (setq textliste '("TEXT" "MTEXT")) (mapcar '(lambda(Texttyp / ) (if(setq as (ssget "x" (list (cons 0 Texttyp)))) (mapcar '(lambda(string / ) (if(setq as (ssget "x" (list (cons 1 string)))) (command "._change" as "" "Eigenschaften" "_color" "4" "") ) ) stringliste ) ) ) textliste ) (princ) ) ------------------ Schöne Grüsse, Morten Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
molo Mitglied Dipl. Ing. Versorgungstechnik
Beiträge: 384 Registriert: 16.07.2002 Windows XP, AutoCAD 2008
|
erstellt am: 30. Okt. 2008 06:31 <-- editieren / zitieren --> Unities abgeben:
Hei Holger, das es so einfach werden würde, hätte ich nicht gedacht! Das ich in meiner Stringliste mit Wildcards arbeiten konnte, habe ich früh gemerkt. Aus irgendeinem Grund hätte ich es aber nicht bei der Objektart eingesetzt. Manchmal sieht man den Wald vor lauter Bäumen nicht. Vielen, vielen Dank für deine Hilfe! Morten (defun mltest (stringliste) (mapcar '(lambda(STRING / AS) (if(setq as (ssget "x" (list (cons 0 "*text") (cons 1 string)))) (command "._change" as "" "Eigenschaften" "_color" "1" "") ) ) STRINGLISTE ) (princ) ) ------------------ Schöne Grüsse, Morten Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Brischke Moderator CAD on demand GmbH
Beiträge: 4187 Registriert: 17.05.2001 AutoCAD 20XX, defun-tools (d-tools.eu)
|
erstellt am: 30. Okt. 2008 06:50 <-- editieren / zitieren --> Unities abgeben: Nur für molo
Hallo Morten, jaja, früh auf. (Was muss das muss!) Ich habe mir mal deine Änderung vorgenommen und diese (erläutert) geändert.
Code:
(defun mlt08 (stringliste / textliste) ;(setq stringliste '("qwe" "asd")) ;-> Das brauch man nicht ;(setq textliste '("TEXT" "MTEXT")) ;<- Das brauch man nicht (mapcar '(lambda(Texttyp / ) (if(setq as (ssget "x" (list (cons 0 ;-> Als Ersatz für TEXT oder MTEXT {Variable Texttyp} ;Kann man hier mit "*TEXT" arbeiten, ;weil Wildcards an dieser Stelle ;unterstützt werden. ;Also heißt es: "*TEXT" )))) (mapcar '(lambda(string / ) (if(setq as (ssget "x" (list (cons 1 string)))) (command "._change" as "" "Eigenschaften" "_color" "4" "") ) ) stringliste ) ) ) textliste ) (princ) );;; Komplett geändert, nach deiner Vorlage (defun mlt08 (stringliste /) (if (setq as (ssget "_X" '((0 . "*TEXT"))));_X, damits auch im engl. ACAD läuft | '((0 . "*TEXT")) kurze Schreibweise möglich, weil ja keine Variablen verwendet werden (mapcar '(lambda(string / ) (if(setq as (ssget "_X" (list (cons 1 string)))) (command "._change" as "" "Eigenschaften" "_color" "4" "") ) ) stringliste ) ) (princ) ) ;;; So sähe es bei mir aus (defun mlt08 (stringliste / ssgetstring as) (setq ssgetstring (substr (apply 'strcat (mapcar '(lambda (TS) (strcat ", " TS) ) stringliste ) ) 2 ) as (ssget "_X" (list '(0 . "*TEXT") (cons 1 ssgetstring) ) ) ) (if as (command "._change" as "" "Eigenschaften" "_color" "4" "")) (princ) )
Zur letzten Variante noch eine Erläuterung, denn die Wildcards sind nicht nur beim GC 0 zu verwenden sondern auch bei allen anderen GCs.Beim SSGET können (wie gesagt Wildcards verwandt werden. Diesen Umstand mache ich mir zu nutze und sammle also alle TEXTE Und MTexte durch Verwendung von "*TEXT" in Verbindung mit dem GC 0 ein. Da ja nur Texte mit bestimmten Inhalt geändert werden sollen (diese sind in der Variablen stringliste als Liste enthalten), baue ich mit dem (apply'strcat ...) einen String der durch Komma getrennte Textmuster enthält -- stringliste:= ("Abc" "CDF") -> "Abc,CDF". Dieser zusammengebaute String wird nun als Filterliste in Verbindung mit dem GC1 verwendet. Alles Klar? Grüße Holger
------------------ Holger Brischke CAD on demand GmbH Individuelle Lösungen von Heute auf Morgen. Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
molo Mitglied Dipl. Ing. Versorgungstechnik
Beiträge: 384 Registriert: 16.07.2002 Windows XP, AutoCAD 2008
|
erstellt am: 30. Okt. 2008 09:24 <-- editieren / zitieren --> Unities abgeben:
Hallo Holger, hab ich soweit verstanden! Nur die (aplay'strcat) Kombination habe ich noch nicht ganz durchgearbeitet/verstanden. Ich scheine zu erkennen, dass man mit substr eine Zeichenkette Teilen kann. Hier anscheinend bleibt der Rest ab dem zweiten Zeichen. [Deswegen eventuell auch ", "?] Mit strcat setze ich Zeichenketten zusammen. Das ich hier zweimal etwas zusammensetze bevor ich es teile, muß ich noch weiter aufschlüsseln. Dafür muß ich erstmal apply mir zu Gemüte führen. Vielen Dank ------------------ Schöne Grüsse, Morten Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Brischke Moderator CAD on demand GmbH
Beiträge: 4187 Registriert: 17.05.2001 AutoCAD 20XX, defun-tools (d-tools.eu)
|
erstellt am: 30. Okt. 2008 09:36 <-- editieren / zitieren --> Unities abgeben: Nur für molo
Hallo Morten, wenn du das (mapcar '(lambda ..)) verstanden hast, dann ist es nur noch ein kleiner Schritt zum (apply '(lambda ..). Das macht nix weiter, als dass es die Funtkion auf alle Listenelemente anwendet. (apply '+ '(1 2 3 4))=> 10 (Addition aller Listenelemente (apply 'strcat '("A" "B" "C"))=>"ABC" (strcat aller Listenelemente) Das (mapcar '(lambda (TS)(strcat ","TS))stringliste) hat ja im Ergebnis eine Liste aus '("A" "B" "C") wird '(",A" ",B" ",C"). Das (apply auf diese Liste losgelassen bringt diesen String: ",A,B,C" Da nun aber das erste Komma nicht gewünscht ist, lasse ich mir mit (substr [STRING] [ABStelle][AnzahlZeichen]) einfach den String ab dem 2.Zeichen zurückgeben, so dass ich dann "A,B,C" habe. Dieser String ist als Wildcard zu gebrauchen. Warum mache ich das anscheinend so kompliziert? Das hat den Grund, dass das mehrmalige (command .. ) auf den jeweiligen Auswahlsatz einfach Zeit kostet. Mit meiner Lösung ist das (command ..) nur einmalig erforderlich, egal, wieviele Zeichenketten du in die Routine reinschickst. Soweit klar? Grüße Holger ------------------ Holger Brischke CAD on demand GmbH Individuelle Lösungen von Heute auf Morgen. Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
molo Mitglied Dipl. Ing. Versorgungstechnik
Beiträge: 384 Registriert: 16.07.2002 Windows XP, AutoCAD 2008
|
erstellt am: 30. Okt. 2008 10:55 <-- editieren / zitieren --> Unities abgeben:
Hallo Holger, so halbwegs ist es klar. Ich lande also bei einem Ausdruck wie in CADmium in 1. Punkt beschrieben hat. Ich habe die Schritte erstmal überflogen und halbwegs nachvolzogen. Da ich mich jetz um andere Dinge kümmern muß, nehme ich das mit nach Hause und schaue es mir in Ruhe nochmal an. Und Nochmal vielen Dank Morten ------------------ Schöne Grüsse, Morten Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
s.wickel Mitglied Bauingenieur Wasserwirtschaft
Beiträge: 422 Registriert: 17.12.2001 Bricscad V7 - V11
|
erstellt am: 30. Okt. 2008 12:43 <-- editieren / zitieren --> Unities abgeben: Nur für molo
Hallo Thomas, Holger, Heiko! Das war eine Hilfe, wie man Sie sich vorstellt. Ich finde es toll, dass ihr so viel Zeit in dieses Forum investiert. Dieser Beitrag ist eine echte Lehrstunde in Sachen LISP. @Morten: Frager die mitdenken und keine fertige Lösung erwarten werden geliebt. Mach' weiter so. Das musste mal gesagt werden. Gruß Stefan
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |