|  |  | 
|  | Gut zu wissen: Hilfreiche Tipps und Tricks aus der Praxis prägnant, und auf den Punkt gebracht für Autodesk Produkte | 
|  |  | 
|  | NVIDIA RTX PRO 6000 Blackwell Max-Q Workstation Edition, eine Pressemitteilung 
 | 
| Autor | Thema:  Listen vergleichen (2436 mal gelesen) | 
 | Andreas Kraus Ehrenmitglied
 Elektrotechniker
 
      
 
      Beiträge: 1519Registriert: 11.01.2006
 WIN 11ACAD 2022
 BricsCAD V25.1.07
 |    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 und AutoLISPler
 
      
 
      Beiträge: 1781Registriert: 11.10.2004
 Window 11ACAD 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 mitVL-PRIN1-TO-STRING prüfen
 ------------------viele Grüße
 Jörnhttp://www.bosse-engineering.com
 Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP | 
                        | Dorfy Mitglied
 Double-Dipl.-Ing. Bleistiftanspitzer
 
    
 
      Beiträge: 900Registriert: 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: 1059Registriert: 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 Ehrenmitglied
 Elektrotechniker
 
      
 
      Beiträge: 1519Registriert: 11.01.2006
 WIN 11ACAD 2022
 BricsCAD V25.1.07
 |    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: 900Registriert: 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 Ehrenmitglied
 Elektrotechniker
 
      
 
      Beiträge: 1519Registriert: 11.01.2006
 WIN 11ACAD 2022
 BricsCAD V25.1.07
 |    erstellt am: 11. Mrz. 2010 14:20  <-- editieren / zitieren -->    Unities abgeben:            
  Ja - hatte ich auch schon probiert. (vlr-acdb-reactornil
 '((: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: 900Registriert: 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: 3341Registriert: 07.07.2006
 ACAD 2006ACAD 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 und AutoLISPler
 
      
 
      Beiträge: 1781Registriert: 11.10.2004
 Window 11ACAD 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örnhttp://www.bosse-engineering.com
 Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |