| |
| Gut zu wissen: Hilfreiche Tipps und Tricks aus der Praxis prägnant, und auf den Punkt gebracht für Autodesk Produkte |
Autor
|
Thema: Summieren von Längen (1527 mal gelesen)
|
cadplayer Ehrenmitglied CADniker
Beiträge: 1832 Registriert: 28.04.2009
|
erstellt am: 06. Mrz. 2015 08:41 <-- editieren / zitieren --> Unities abgeben:
Hi! Steh irgendwie grad auf dem Schlauch und komme nicht richtig weiter Ich möchte bei folgender Liste die Werte addieren, bei denen der Radius gleich ist Code: (setq lst (list '( (("Length" . 7.7051) ("Radius" . 0.0)) (("Length" . 7.49192) ("Radius" . 5.0)) (("Length" . 5.04972) ("Radius" . 0.0)) (("Length" . 5.35758) ("Radius" . 5.0)) (("Length" . 5.74767) ("Radius" . 0.0)) (("Length" . 7.7051) ("Radius" . 1.0)) (("Length" . 7.49192) ("Radius" . 3.0)) (("Length" . 5.04972) ("Radius" . 3.0)) (("Length" . 5.35758) ("Radius" . 0.0)) (("Length" . 5.74767) ("Radius" . 1.0)) ) ) )
Bin ich mit meinem Ansatz auf dem richtigen Weg oder ist es zu kompliziert gedacht?! Code: (setq i -1)(mapcar (function (lambda(x) (setq r (cdr (assoc "Radius" (nth i x))) l (cdr (assoc "Length" (nth i x))) ) (if (= r (cdr (assoc "Radius" x))) (setq sumL (+ l (cdr (assoc "Length" x)))) ) ) ) lst )
------------------ Gruss Dirk Blog | Adolf Spende | Infra-Feed
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
CADmium Moderator Maschinenbaukonstrukteur
Beiträge: 13508 Registriert: 30.11.2003 .
|
erstellt am: 06. Mrz. 2015 10:18 <-- editieren / zitieren --> Unities abgeben: Nur für cadplayer
(setq lst '( (("Length" . 7.7051) ("Radius" . 0.0)) (("Length" . 7.49192) ("Radius" . 5.0)) (("Length" . 5.04972) ("Radius" . 0.0)) (("Length" . 5.35758) ("Radius" . 5.0)) (("Length" . 5.74767) ("Radius" . 0.0)) (("Length" . 7.7051) ("Radius" . 1.0)) (("Length" . 7.49192) ("Radius" . 3.0)) (("Length" . 5.04972) ("Radius" . 3.0)) (("Length" . 5.35758) ("Radius" . 0.0)) (("Length" . 5.74767) ("Radius" . 1.0)) ) ) (defun SUM(LST / RL1 RL2) (setq RL1 (mapcar '(lambda(X)(cdr(assoc "Radius" X))) LST)) (while RL1 (setq RL2 (cons (car RL1) RL2))(setq RL1(vl-remove (car RL1) RL1))) (mapcar '(lambda(X) (list (cons "Radius" X) (apply '+ (mapcar '(lambda(Z) (cdr(assoc "Length" Z))) (vl-remove-if-not '(lambda(Y) (= X(cdr(assoc "Radius" Y)))) LST) ) ) ) ) RL2 ) ) (SUM LST) ------------------ Also ich finde Unities gut ... und andere sicher auch --------------------------------------- - 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 |
Meldin Mitglied
Beiträge: 381 Registriert: 15.07.2011 ACA2020 Windows10
|
erstellt am: 06. Mrz. 2015 11:43 <-- editieren / zitieren --> Unities abgeben: Nur für cadplayer
Äh ja hatte die Antwort von Cadmium zu spät gesehen. Aber du siehst viele Wege führen nach Rom. Daher hier noch mein geistiger Erguss. Code: (setq MeineListe '( (("Length" . 7.7051) ("Radius" . 0.0)) (("Length" . 7.49192) ("Radius" . 5.0)) (("Length" . 5.04972) ("Radius" . 0.0)) (("Length" . 5.35758) ("Radius" . 5.0)) (("Length" . 5.74767) ("Radius" . 0.0)) (("Length" . 7.7051) ("Radius" . 1.0)) (("Length" . 7.49192) ("Radius" . 3.0)) (("Length" . 5.04972) ("Radius" . 3.0)) (("Length" . 5.35758) ("Radius" . 0.0)) (("Length" . 5.74767) ("Radius" . 1.0)) ) )(defun AddListe (MListe / MeineListe1Radius Länge ERG) (while MListe (setq MeineListe1Radius (cadar MListe)) (setq Länge 0.0) (setq MListe (vl-remove-if-not '(lambda (x)(if (= (cdr MeineListe1Radius) (cdadr x)) (progn (setq Länge (+ Länge (cdar x))) nil) x))MListe)) (setq ERG (cons (cons MeineListe1Radius Länge) ERG)) ) ) (ADDLISTE MeineListe)
------------------ Gruß Wolfgang Alias: Rabbit007 und Wolli1 Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
cadplayer Ehrenmitglied CADniker
Beiträge: 1832 Registriert: 28.04.2009
|
erstellt am: 06. Mrz. 2015 12:13 <-- editieren / zitieren --> Unities abgeben:
|
Meldin Mitglied
Beiträge: 381 Registriert: 15.07.2011 ACA2020 Windows10
|
erstellt am: 06. Mrz. 2015 13:13 <-- editieren / zitieren --> Unities abgeben: Nur für cadplayer
hier noch nachgeschoben eine kürzere und übersichtlichere Fassung Code: (setq MeineListe '( (("Length" . 7.7051) ("Radius" . 0.0)) (("Length" . 7.49192) ("Radius" . 5.0)) (("Length" . 5.04972) ("Radius" . 0.0)) (("Length" . 5.35758) ("Radius" . 5.0)) (("Length" . 5.74767) ("Radius" . 0.0)) (("Length" . 7.7051) ("Radius" . 1.0)) (("Length" . 7.49192) ("Radius" . 3.0)) (("Length" . 5.04972) ("Radius" . 3.0)) (("Length" . 5.35758) ("Radius" . 0.0)) (("Length" . 5.74767) ("Radius" . 1.0)) ) )(defun AddListe (MListe / MeineListe1Radius Länge ERG) (while MListe (setq MeineListe1Radius (cadar MListe) Länge 0.0 MListe (vl-remove-if'(lambda (x)(and (= (cdr MeineListe1Radius) (cdadr x)) (setq Länge (+ Länge (cdar x)))))MListe) ERG (cons (cons MeineListe1Radius Länge) ERG))) ) (ADDLISTE MeineListe)
------------------ Gruß Wolfgang Alias: Rabbit007 und Wolli1 Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
archtools Mitglied
Beiträge: 823 Registriert: 09.10.2004 Entwickler für AutoCAD, BricsCAD u.a., alle Systeme
|
erstellt am: 06. Mrz. 2015 15:42 <-- editieren / zitieren --> Unities abgeben: Nur für cadplayer
Zitat: Original erstellt von cadplayer: Hi! Steh irgendwie grad auf dem Schlauch und komme nicht richtig weiter Ich möchte bei folgender Liste die Werte addieren, bei denen der Radius gleich ist
Code: (setq lst (list '( (("Length" . 7.7051) ("Radius" . 0.0)) (("Length" . 7.49192) ("Radius" . 5.0)) (("Length" . 5.04972) ("Radius" . 0.0)) (("Length" . 5.35758) ("Radius" . 5.0)) (("Length" . 5.74767) ("Radius" . 0.0)) (("Length" . 7.7051) ("Radius" . 1.0)) (("Length" . 7.49192) ("Radius" . 3.0)) (("Length" . 5.04972) ("Radius" . 3.0)) (("Length" . 5.35758) ("Radius" . 0.0)) (("Length" . 5.74767) ("Radius" . 1.0)) ) ) )
Bin ich mit meinem Ansatz auf dem richtigen Weg oder ist es zu kompliziert gedacht?!
Du hast ja schon etliche elegante Lösungen für diesen Spezialfall erhalten. Hier noch meine 5 Cent, die darauf aufbauen, dass man eine umfangreiche Bibliothek aus Standardfunktionen hat, die man immer wieder flexibel einsetzen kann. Verwendet werden hier meine &SUBST und &SUBSTAPPEND Funktionen. &SUBST funktioniert für Assoc-Listen wie SUBST, außer dass man nicht extra nachsehen muss, ob das Element schon in der Liste ist. Man braucht deshalb nicht anzugeben, welches Element in der Liste ersetzen werden soll. &SUBSTAPPEND ist ähnlich. Wird in einer Liste eine Assoc-Teilliste ("A" 1 2 3) gefunden und soll ("A" 4 5) "substappendiert" werden, dann steht in der Ergebnisliste dann ("A" 1 2 3 4 5) drin. Mal testen: (setq lst '(("A" 1 2 3) ("B" 10 11 12))) (&substappend '("A" 4 5) lst) -> (("A" 1 2 3 4 5) ("B" 10 11 12)) Code:
(defun &subst (ntok lst / temp) (cond ((not lst) (list ntok) ; lst existiert nicht ) ((setq temp (assoc (car ntok) lst)) (subst ntok temp lst) ; existiert schon, ersetzen ) ('T (reverse (cons ntok (reverse lst))) ; hinten dran ) ) )(defun &substappend (tok lst / ntok) (if (setq ntok (assoc (car tok) lst)) (&subst (append ntok (cdr tok)) lst) (&subst tok lst) ) ) ;; Hat man diese Bibliotheksfunktionen, dann sieht die Lösung so ;; aus: (setq nlst nil) (mapcar '(lambda (tok) (setq nlst (&substappend (list (cdadr tok) (cdar tok)) nlst))) lst ) ;; NLST ist dann eine Assoc-Liste mit dem Radius als jeweils ;; erstem (Assoc-) Element und darauf folgend alle Längen, die für ;; diesen Radius in der LST stehen. ;; Die Längenaddition für jeden Radius kriegt man dann so: (mapcar '(lambda (tok) (list (car tok) (apply '+ (cdr tok)))) nlst)
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
cadplayer Ehrenmitglied CADniker
Beiträge: 1832 Registriert: 28.04.2009
|
erstellt am: 06. Mrz. 2015 19:11 <-- editieren / zitieren --> Unities abgeben:
|
archtools Mitglied
Beiträge: 823 Registriert: 09.10.2004 Entwickler für AutoCAD, BricsCAD u.a., alle Systeme
|
erstellt am: 06. Mrz. 2015 19:34 <-- editieren / zitieren --> Unities abgeben: Nur für cadplayer
Zitat: Original erstellt von cadplayer: Ich schau mir auf jeden Fall "genüsslich" die 2 weiteren Lösungen zu meinenem Problem an Vielen Dank für die rege Beteiligung und die interessanten Wege, wie ih die Sache angeht. Habe ich da etwa den Nerv der Lispler getroffen ?!
Klar. Lisp ist die mit Abstand eleganteste Programmiersprache, die Programmierer immer wieder zu neuen, möglichst eleganten Lösungen anspornt. Es gibt regelrechte Wettbewerbe dafür, was ich von sonst keiner anderen Programmiersprache kenne. Das ist ein wenig wie das Lösen von Logicals.
Wenn uns Lisplern also eine Aufgabe begegnet, die den Ehrgeiz zu einer besonders eleganten Lösung weckt, dann sind wir alle dabei. Ich kam allerdings zu spät für die elegante Lösung, weshalb ich auf die Standardlösung aus Bibliotheksfunktionen verwiesen habe. Die hat IMO den Vorteil, dem Anfänger die Denke von Lisplern aufzuzeigen: ein spezielles Problem in möglichst einfach lösbare allgemeine Probleme zu zerlegen.
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |