| |
| Gut zu wissen: Hilfreiche Tipps und Tricks aus der Praxis prägnant, und auf den Punkt gebracht für Autodesk Produkte |
| |
| PNY bietet das umfangreichste Ökosystem von B2B als auch B2C-Lösungen für IT-Akteure auf dem Markt, eine Pressemitteilung
|
Autor
|
Thema: Listen vergleichen (2087 mal gelesen)
|
Andreas Kraus Mitglied Elektrotechniker
Beiträge: 1455 Registriert: 11.01.2006 WIN 10 ACAD 2022 BricsCAD V23
|
erstellt am: 11. Mrz. 2010 09:15 <-- editieren / zitieren --> Unities abgeben:
Hallo zusammen, ist zwar ein bekanntes Thema aber so richtig gefunden hab ich nix. Ich habe zwei Listen mit den Objektdaten die man mit entget bekommt. Brauchen tu ich: Welches Element ist in Liste1 und NICHT in Liste2 Welches Element ist in Liste2 und NICHT in Liste1 Welches Element ist in Liste1 und VERÄNDERT in Liste2 Einfacher: Was ist neu, was ist gelöscht, was ist geändert ? Ein Vergleich mit z.B. (setq data_alt_list (vl-remove-if '(lambda (data) (member data k_index_all_data_neu)) k_index_all_data_alt ) ) ist bei über 30000 Elementen recht langsam. Hat jemand ne Idee wie ich eine solche Auswertung schneller machen kann ?
------------------ Gruß Andreas http://kraus-cad.de Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
joern bosse Ehrenmitglied Dipl.-Ing. Vermessung
Beiträge: 1763 Registriert: 11.10.2004 Window 11 ACAD 2021 CIVIL 2021 BricsCAD ab V14 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz 2.80 GHz 32.0GB RAM NVIDIA GeForce MX450<P>
|
erstellt am: 11. Mrz. 2010 10:16 <-- editieren / zitieren --> Unities abgeben: Nur für Andreas Kraus
Hallo Andreas, hast Du grundsätzlich Listenelemente, die über einen GC angesprochen werden können?? Dann könntest Du zumindestens anstelle des MEMBER ein ASSOC verwenden, das dürfte dann schon ein wenig schneller gehen. (setq k_index_all_data_alt (vl-remove-if '(lambda(data) (assoc(car data)k_index_all_data_neu)) k_index_all_data_alt)) Desweiteren könntest Du den CDR-Inhalt der Liste dann mit VL-PRIN1-TO-STRING prüfen ------------------ viele Grüße Jörn http://www.bosse-engineering.com 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: 11. Mrz. 2010 12:36 <-- editieren / zitieren --> Unities abgeben: Nur für Andreas Kraus
Zitat: Original erstellt von Andreas Kraus: ... Ich habe zwei Listen mit den Objektdaten die man mit entget bekommt.Brauchen tu ich: Welches Element ist in Liste1 und NICHT in Liste2 Welches Element ist in Liste2 und NICHT in Liste1 Welches Element ist in Liste1 und VERÄNDERT in Liste2 ... ist bei über 30000 Elementen recht langsam. Hat jemand ne Idee wie ich eine solche Auswertung schneller machen kann ?
30000 "Elemente" in der List die du mit entget erstellt hast? oder 30000 Objekte/Listen die miteinander/mit einer Liste abgeglichen werden sollen? Zitat: Original erstellt von Andreas Kraus: ... Einfacher: Was ist neu, was ist gelöscht, was ist geändert ? ... Hat jemand ne Idee wie ich eine solche Auswertung schneller machen kann ?
Wofür das Ganze? Zeichnungen/Objekte abgleichen? Wenn ein GC öfters vorkommt (ich denke da gerade an polylines/vertext), wie soll das gehändelt werden? Spielt die Position in der Liste eine Rolle? ------------------ Mfg Heiko Elefantenjagd in Afrika "... LISP-Programmierer bauen einen Irrgarten aus Klammern und hoffen, dass sich der Elefant darin verirrt..." (www.uni-leipzig.de/~rotheh/elefant.htm) 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: 11. Mrz. 2010 13:28 <-- editieren / zitieren --> Unities abgeben: Nur für Andreas Kraus
Zitat: Original erstellt von joern bosse: Hallo Andreas, hast Du grundsätzlich Listenelemente, die über einen GC angesprochen werden können??Dann könntest Du zumindestens anstelle des MEMBER ein ASSOC verwenden, das dürfte dann schon ein wenig schneller gehen.
Das Problem dabei ist erstens, dass einzelne GCs mehrfach vorkommen können, und zweitens, dass die Reihenfolge wichtig sein kann. Das macht sowohl Deinen Lösungsversuch unbrauchbar, als auch den, den man als Antwort den OP normalerweise geben würde, sich nämlich Bool'sche Operatoren für Listen zu basteln. Wegen so dummer DXF-Daten wie z.B. denen von MTexten gibt es IMO prinzipiell keine allgemeingültige Lösung. Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Andreas Kraus Mitglied Elektrotechniker
Beiträge: 1455 Registriert: 11.01.2006 WIN 10 ACAD 2022 BricsCAD V23
|
erstellt am: 11. Mrz. 2010 13:32 <-- editieren / zitieren --> Unities abgeben:
@Heiko Ich brauche ein Protokoll Wer, wann, was geändert hat. Also hab ich mir gedacht: Beim öffnen ALLE Objektdaten in eine Liste und beim Speichern mit dem IST-Stand vergleichen. Soweit die Theorie An die Auswertung von Polylines oder auch Blöcken mit Attributen bin ich noch nicht gekommen, da mich die Laufzeit bei größeren Zeichnungen noch nervt. Wenn ich alles was unverändert ist aus den Listen rausschmeißen könnte, hätte ich schon viel weniger zu verarbeiten aber das dauert ja genau so lange (also nix gewonnen). Vielleicht brauch ich ja auch einen komplett anderen Ansatz. ------------------ Gruß Andreas http://kraus-cad.de 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: 11. Mrz. 2010 13:40 <-- editieren / zitieren --> Unities abgeben: Nur für Andreas Kraus
hi, reactor -Einsatz wäre mein erster gedanke... Edit: siehe Database reactor events ------------------ Mfg Heiko Elefantenjagd in Afrika "... LISP-Programmierer bauen einen Irrgarten aus Klammern und hoffen, dass sich der Elefant darin verirrt..." (www.uni-leipzig.de/~rotheh/elefant.htm) [Diese Nachricht wurde von Dorfy am 11. Mrz. 2010 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Andreas Kraus Mitglied Elektrotechniker
Beiträge: 1455 Registriert: 11.01.2006 WIN 10 ACAD 2022 BricsCAD V23
|
erstellt am: 11. Mrz. 2010 14:20 <-- editieren / zitieren --> Unities abgeben:
Ja - hatte ich auch schon probiert. (vlr-acdb-reactor nil '((:vlr-objectModified . work_objectModified)) ) bzw. :vlr-objectErased und :vlr-objectAppended Damit könnte ich wenigstens die Listen der neuen, gelöschten und geänderten Objekte erstellen. Allerdings ist das schon Fummelei wenn z.B. ein neues Objekt kurz darauf gelöscht oder geändert wird, dann taucht es in verschiedenen Listen auf. Kann man aber raussortieren. Hmmm... so richtig glücklich bin ich damit noch nicht, aber wenns schneller geht ... mal probiern. ------------------ Gruß Andreas http://kraus-cad.de 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: 11. Mrz. 2010 14:52 <-- editieren / zitieren --> Unities abgeben: Nur für Andreas Kraus
Zitat: Original erstellt von Andreas Kraus:
Allerdings ist das schon Fummelei .... Hmmm... so richtig glücklich bin ich damit noch nicht, aber wenns schneller geht ... mal probiern.
Ein wenig Bastelarbeit wird es schon werden, so oder so... siehe Beitrag von Tom - mit der Variante Vorher-Nachher-Vergleich, ist der Aufwand enorm. Und so brauchst du nur wenige Listen (drei ggf. vier Gesamtprotokoll)beim neu/ändern/löschen je nach Vorgang prüfen und ändern. ------------------ Mfg Heiko Elefantenjagd in Afrika "... LISP-Programmierer bauen einen Irrgarten aus Klammern und hoffen, dass sich der Elefant darin verirrt..." (www.uni-leipzig.de/~rotheh/elefant.htm) Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Entsorger01 Ehrenmitglied V.I.P. h.c. Techniker
Beiträge: 3310 Registriert: 07.07.2006 ACAD 2006 ACAD 2008 - SP1 VPstudio (Raster) Acrobat 7.0 Prof. Acrobat Distiller Photoshop CS2 Nvidia Quadro FX1400 Win 2000 Prof.
|
erstellt am: 11. Mrz. 2010 15:04 <-- editieren / zitieren --> Unities abgeben: Nur für Andreas Kraus
|
joern bosse Ehrenmitglied Dipl.-Ing. Vermessung
Beiträge: 1763 Registriert: 11.10.2004 Window 11 ACAD 2021 CIVIL 2021 BricsCAD ab V14 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz 2.80 GHz 32.0GB RAM NVIDIA GeForce MX450<P>
|
erstellt am: 11. Mrz. 2010 17:05 <-- editieren / zitieren --> Unities abgeben: Nur für Andreas Kraus
Hallo Andreas, ich habe noch ein wenig experimentiert, das Ergebnis ist eine Funktion, die die alte Gruppencodeliste pro angepickten Element erstmal wegspeichert in "c:LvStore.lsp", als Kennung wird der GC5 verwendet. (Das heißt aber, bei copy And Paste funzt es dann nicht mehr) Wenn das Element das 2.te Mal angepickt wird kann bereits ein Vergleich stattfinden zwischen gespeicherter und aktueller Gruppencodeliste. Doppelte Gruppencodes habe ich mit einem aufzählenden Index berücksichtigt. Wenn die Reihenfolge wichtig ist (@ Tom), dann ist das noch nicht berücksichtigt. Manko: ich habe die Einträge hinter den GC's als String gespeichert, d.h. bei REAL-Zahlen werden tlw. nur eine Nachkommastelle gespeichert. Das kann man vor dem Speichern sicherlich mit TYPE abfangen, ist aber aufwendig. Letztendlich ist es nur Spielerei, denn ob sich dieses Verfahren eignet um umfangreiche Zeichnungen zu prüfen ist fraglich, aber mir hatte es gerade Spaß gemacht. Code:
(defun c:Lv ( / ) (setq liste (LvRestoreGetList)) (if(setq obj (car(entsel "\nBitte Objekt picken"))) (progn (setq gc5 (cdr(assoc 5 (entget obj))) obj_liste (LvList(entget obj))) (if (assoc gc5 liste) (progn (LvAlert (LvVergleich obj_liste (cadr(assoc gc5 liste)))) (JBf_list_sichern (subst (list gc5 obj_liste) (assoc gc5 liste)liste)"c:\\LvStore.lsp")) (progn (alert "Das Objekt wurde noch nicht gespeichert, daher kein Vergleich.") (JBf_list_sichern (cons(list gc5 obj_liste)liste)"c:\\LvStore.lsp")))) (alert "kein Objekt gepickt."))) ;;;Listevergleich ;;;1 = unverändert ;;;2 = verändert ;;;3 = neu hinzugekommen ;;;4 = nicht mehr vorhanden
(defun LvVergleich (liste_new liste_old / ) (append (mapcar '(lambda(A) (cond ((assoc (car A)liste_old);;;vorhanden in alter Liste (if(=(cdr A)(cdr(assoc (car A)liste_old))) (list 1 A nil);;;unverändert (list 2 A (assoc (car A)liste_old)));;;verändert ) ((not (assoc (car A)liste_old)) (list 3 A nil));;;neu hinzugekommen, in alter Liste nicht ;;;vorhanden ))liste_new) (mapcar '(lambda(A) (list 4 A nil)) (vl-remove-if '(lambda(A)(assoc (car A)liste_new))liste_old)))) (defun LvAlert (liste / msg) (setq msg (apply 'strcat (vl-remove-if 'not (mapcar '(lambda(A) (cond ((=(car A) 3) (strcat "NEU:" (cdr(cadr A))"\n")) ((=(car A) 2) (strcat "VERÄNDERT: \n(NEU)"(cdr(cadr A))"\n(ALT)"(cdr(caddr A))"\n")) ((=(car A) 4) (strcat "NICHT MEHR VORHANDEN:" (cdr(cadr A))))))liste)))) (alert (if (/= msg "") msg "Keine Änderung")))
(defun LvList (liste / A gc_liste) (mapcar '(lambda(A) (if (assoc (car A)gc_liste) (progn (setq gc_liste (subst(list (car A) (+(cadr(assoc (car A)gc_liste))1)) (assoc(car A)gc_liste)gc_liste)) (cons (strcat(itoa(car A))"|"(itoa(cadr(assoc(car A)gc_liste))))(vl-prin1-to-string A))) (progn (setq gc_liste (cons (list (car A) 10000)gc_liste)) (cons (itoa(car A))(vl-prin1-to-string A)))))liste)) (defun LvRestoreGetList ( / ) (if (findfile "c:\\LvStore.lsp") (load "c:\\LvStore.lsp")))
(defun JBf_list_sichern (liste pfad / datei ) (setq datei (open pfad "w")) (write-line "'(" datei) (mapcar '(lambda(A) (prin1 A datei))liste) (write-line ")" datei) (close datei))
------------------ viele Grüße Jörn http://www.bosse-engineering.com Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |