| |
| 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: MAPCAR - Listen mit unterschiedlicher Länge (1352 mal gelesen)
|
gmk Mitglied Dipl.-Ing.(FH) Vermessung
Beiträge: 669 Registriert: 23.10.2002 Autocad 2004, WS CadCompass, Normica V2000, WinXP Prof., AMD Athlon 64 X2, 2GB, NVIDIA GeForce 7600GS, HP1055CM
|
erstellt am: 01. Jul. 2009 12:03 <-- editieren / zitieren --> Unities abgeben:
Servus! Ich habe so eine Liste: '((1 2 3) (A B C D) (a b)) Wie komme ich auf dieses Ergebnis '((1 A a) (2 B b) (3 C) (nil D)) ? Ich denke MAPCAR ist die richtige Funktion. Aber wie übergebe ich die Unterlisten an MAPCAR und wie bekomme ich das nil? Könnte natürlich die Längen vergleichen und mit nil auffüllen. Evtl. geht's aber einfacher? Ciao Georg
------------------ http://www.xxx-tausend.info Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
CADmium Moderator Maschinenbaukonstrukteur
Beiträge: 13527 Registriert: 30.11.2003 .
|
erstellt am: 01. Jul. 2009 12:25 <-- editieren / zitieren --> Unities abgeben: Nur für gmk
so ? (setq LISTE'((1 2 3) ("A" "B" "C" "D") ("a" "b"))) (setq RESULT nil) (repeat(apply 'max(mapcar '(lambda(X) (length X))LISTE)) (setq RESULT(cons(list(mapcar 'car LISTE)) RESULT)) (setq LISTE (mapcar 'cdr LISTE)) ) (reverse RESULT) ------------------ - 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 |
gmk Mitglied Dipl.-Ing.(FH) Vermessung
Beiträge: 669 Registriert: 23.10.2002 Autocad 2004, WS CadCompass, Normica V2000, WinXP Prof., AMD Athlon 64 X2, 2GB, NVIDIA GeForce 7600GS, HP1055CM
|
erstellt am: 01. Jul. 2009 13:22 <-- editieren / zitieren --> Unities abgeben:
Zitat: Original erstellt von CADmium: so ?(setq LISTE'((1 2 3) ("A" "B" "C" "D") ("a" "b"))) (setq RESULT nil) (repeat(apply 'max(mapcar '(lambda(X) (length X))LISTE)) (setq RESULT(cons (mapcar 'car LISTE) RESULT)) <------------LIST enfernt (setq LISTE (mapcar 'cdr LISTE)) ) (reverse RESULT)
Super! Hab' noch das LIST rausgenommen (s.o.) so passt es 1a. Coole Idee das nil aus dem Rückgabewert zu verwenden.
Das mit dem CONS hatte ich auch schon + eine FOREACH-Schleife; hätte aber jede LISTE mit fehlenden NILs auffüllen müssen. Vielen Dank! Ciao Georg
------------------ http://www.xxx-tausend.info Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
archtools Mitglied
Beiträge: 965 Registriert: 09.10.2004 Entwickler für AutoCAD, BricsCAD u.a., alle Systeme
|
erstellt am: 01. Jul. 2009 19:33 <-- editieren / zitieren --> Unities abgeben: Nur für gmk
Zitat: Original erstellt von gmk: Super! Hab' noch das LIST rausgenommen (s.o.) so passt es 1a. Coole Idee das nil aus dem Rückgabewert zu verwenden.Das mit dem CONS hatte ich auch schon + eine FOREACH-Schleife; hätte aber jede LISTE mit fehlenden NILs auffüllen müssen. Vielen Dank! Ciao Georg
Hier noch eine andere Variante, die theoretisch noch einen Tick schneller läuft und mit weniger Funktionsaufrufen auskommt: Code:
(setq lst '((1 2 3) (A B C D) (a b)))(while (apply 'or (setq tok (mapcar 'car lst))) (setq result (cons tok result) lst (mapcar 'cdr lst) ) ) (reverse result)
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
CADmium Moderator Maschinenbaukonstrukteur
Beiträge: 13527 Registriert: 30.11.2003 .
|
erstellt am: 01. Jul. 2009 20:12 <-- editieren / zitieren --> Unities abgeben: Nur für gmk
Zitat: Original erstellt von archtools: Hier noch eine andere Variante, die theoretisch noch einen Tick schneller läuft und mit weniger Funktionsaufrufen auskommt:Code:
(setq lst '((1 2 3) (A B C D) (a b)))(while (apply 'or (setq tok (mapcar 'car lst))) (setq result (cons tok result) lst (mapcar 'cdr lst) ) ) (reverse result)
.. auch sehr schön, vor allem kompakt ... wie ist es mit Laufzeit testen ? ------------------ - 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 |
autocart Mitglied Technischer Redakteur
Beiträge: 698 Registriert: 08.09.2003
|
erstellt am: 02. Jul. 2009 02:45 <-- editieren / zitieren --> Unities abgeben: Nur für gmk
... und wenn man die "hinteren" nils auch noch weg haben will (wie ganz genau von der ersten Formulierung der Frage abgeschaut), dann kann man es so machen: Code: (setq lst '((1 2 3) (A B C D) (a b)))(while (apply 'or (setq tok (mapcar 'car lst))) (if (not (apply 'and tok)) (progn (setq tok (reverse tok)) (while (not (car tok)) (setq tok (cdr tok)) ) (setq result (cons (reverse tok) result)) ) (setq result (cons tok result)) ) (setq lst (mapcar 'cdr lst)) ) (reverse result)
------------------ Gruß, Stephan www.stbartl.at "Every thing should be made as simple as possible but not simpler." - Albert Einstein [Diese Nachricht wurde von autocart am 02. Jul. 2009 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
archtools Mitglied
Beiträge: 965 Registriert: 09.10.2004 Entwickler für AutoCAD, BricsCAD u.a., alle Systeme
|
erstellt am: 02. Jul. 2009 09:57 <-- editieren / zitieren --> Unities abgeben: Nur für gmk
Zitat: Original erstellt von CADmium: .. auch sehr schön, vor allem kompakt ... wie ist es mit Laufzeit testen ? :D
Das hat mich überrascht. Ich hatte gedacht, dass bei kurzen Listen meine Lösung schneller ist. Da muss zwar bei jedem Schleifendurchlauf mit OR getestet werden, aber ich hatte angenommen, dass das bei bis zu vielleicht 100 Listenelementen schneller ist als der einmalige Aufruf von MAX und LENGTH und der LAMBDA-Konstruktion bei der REPEAT-Schleife. Aber schon bei diesen kurzen Listen ist meine Lösung viermal langsamer als die Deine. So bleibt mir nur noch der Preis für Eleganz :-) Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
CADmium Moderator Maschinenbaukonstrukteur
Beiträge: 13527 Registriert: 30.11.2003 .
|
erstellt am: 02. Jul. 2009 10:03 <-- editieren / zitieren --> Unities abgeben: Nur für gmk
... der auf jeden Fall ... (while (apply 'or (setq tok (mapcar 'car lst))) also das apply aufs 'or anwenden find ich super. .. Ein Konstrukt, den man bestimmt auch mal woanders anwenden kann ( wenn man sich dann gleich daran erinnert ) Fazit : Mal wieder ein schöner Thread , der Spaß macht!
------------------ - 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 |
archtools Mitglied
Beiträge: 965 Registriert: 09.10.2004 Entwickler für AutoCAD, BricsCAD u.a., alle Systeme
|
erstellt am: 02. Jul. 2009 10:44 <-- editieren / zitieren --> Unities abgeben: Nur für gmk
Zitat: Original erstellt von CADmium: ... der auf jeden Fall ... (while (apply 'or (setq tok (mapcar 'car lst))) also das apply aufs 'or anwenden find ich super. .. Ein Konstrukt, den man bestimmt auch mal woanders anwenden kann
Das war der wesentliche Grund, warum ich das gepostet hatte. Diese Boole'schen Operatoren werden von den meisten Lisp-Programmierern völlig unterschätzt und deshalb viel zu selten angewendet. Hier mal eine Variante, die ich häufig einsetze, um Anwender daran zu hindern, in einer Dialogbox unzulässige Zeichen einzugeben: Code:
(setq oldstrvalue "TEST" strvalue (getstring "\nTextzeile angeben: ") )(cond ((apply 'OR (mapcar (function (lambda (zeichen) (member zeichen (vl-string->list strvalue)) ) ) '(42 63 39 64 124 47 38) ) ) (alert "Fehler\n\nName darf keines dieser Zeichen enthalten:\n* ? ' @ | / &!" ) oldstrvalue ) ;; .... )
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
CADmium Moderator Maschinenbaukonstrukteur
Beiträge: 13527 Registriert: 30.11.2003 .
|
erstellt am: 02. Jul. 2009 10:56 <-- editieren / zitieren --> Unities abgeben: Nur für gmk
ok .. wenn wir schon dabei sind ... das würd ich dann so machen : (setq oldstrvalue "TEST" strvalue (getstring "\nTextzeile angeben: ") ) (cond ((vl-every '(lambda(X) (not(member X '(42 63 39 64 124 47 38)))) (vl-string->list strvalue) ) ) (alert "Fehler\n\nName darf keines dieser Zeichen enthalten:\n* ? ' @ | / &!" ) ('T oldstrvalue) ) Hoffentlich kriegt der Threadersteller nicht immer ne Benachrichtigungsmail ... aber ich denke, ein wenig Offtopic ist in dem Fall erlaubt.
------------------ - 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 |