Arrays vergleichen und doppelte Einträge löschen.

  • Hi,

    wie fang ich am Besten an.
    Ich lese heute alle Verzeichnisse & Dateiorte ein und speichere diese mit in Dir_$datum.txt.
    Das Gleiche mache ich am nächsten Tag auch.

    Jetzt sind innerhalb dieser 24 Stunden neue Verzeichnisse dazugekommen.
    Also lese ich Dir_gestern.txt und Dir_heute.txt in ein Array rein und möchte diese Arrays vergleichen.

    Jetzt gibts da was schickes von Bugfix & alternativ nochwas vom au3b**.de.

    Spoiler anzeigen
    [autoit]

    Func _ArrayCompare($avArray1, $avArray2)
    ; PenGuin :O
    ; Array[0] = Anzahl an Treffer
    Local $avArray3[1] = [0], $iMax, $i
    For $i = 0 To UBound($avArray1) - 1
    If Not _c($avArray2, $avArray1[$i]) Then
    $iMax = UBound($avArray3)
    ReDim $avArray3[$iMax + 1]
    $avArray3[$iMax] = $avArray1[$i]
    EndIf
    Next
    $avArray3[0] = UBound($avArray3) - 1
    Return $avArray3
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _c($a, $v)
    Local $i
    For $i = 0 To UBound($a) - 1
    If $a[$i] = $v Then Return True
    Next
    Return False
    EndFunc

    [/autoit]

    Leider dauert das Ganze bei ca. 20000 Einträgen ziemlich lange.
    Des Weiteren liefert mir das Ganze das nicht so, wie ichs gern hätte.

    Ich möchte die Verzeichnisse vergleichen und die doppelten Einträge rauslöschen. Sodass ich nur die Verzeichnisse habe, die dazugekommen sind.

    Grüße

    Kev

    Einmal editiert, zuletzt von Kev (23. Februar 2012 um 09:01)

  • Hab jetzt grade keine 20k Einträge da von daher keine Ahnung obs so schneller geht (ungetestet!):

    Spoiler anzeigen
    [autoit]

    Func _neuedir($Dir_gestern, $Dir_heute)
    _ArraySort($Dir_heute)
    For $element In $Dir_gestern
    _ArrayDelete($Dir_heute, _ArrayBinarySearch($Dir_heute, $element))
    Next
    Return $Dir_heute
    EndFunc ;==>_neuedir

    [/autoit]

    Andy hat mir ein Schnitzel gebacken aber da war ein Raupi drauf und bevor Oscar das Bugfixen konnte kam Alina und gab mir ein AspirinJunkie.

    2 Mal editiert, zuletzt von chip (22. Februar 2012 um 16:24)

  • Wie Chip schon für seine Unfähigkeit verurteilt, funktioniert dieses Script nicht..oder...es dauert zu lange. VIel zu lange..sehr lange. :D
    Desweiteren möchte ich die Disfunktionalität beteuern und ein Austausch meiner zuvor genannten Erwähnung von 20k auf 154k Einträgen vornehmen.
    Alternative Möglichkeiten?

    Einmal editiert, zuletzt von Kev (22. Februar 2012 um 16:36)

  • Alternative
    [autoit]

    Global $a_Array1[10] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] ; 1. Array
    Global $a_Array2[10] = [6, 7, 3, 12, 9, 4, 1, 2, 14, 5] ; 2. Array

    [/autoit] [autoit][/autoit] [autoit]

    Global $dic_A1 = ObjCreate("Scripting.Dictionary") ; Dictionary für die Einträge des ersten Arrays
    Global $s_Ret = ""

    [/autoit] [autoit][/autoit] [autoit]

    ; Array in Dictionary überführen:
    For $i In $a_Array1
    $dic_A1($i) = 0
    Next

    [/autoit] [autoit][/autoit] [autoit]

    ; 2. Array durchgehen und auf Unterschiede zum 1. Array prüfen:
    For $i In $a_Array2
    If Not $dic_A1.Exists($i) Then $s_Ret &= $i & @CRLF
    Next

    [/autoit] [autoit][/autoit] [autoit]

    ; Unterschiede ausgeben:
    MsgBox(0, "", "Unterschiedliche Elemente:" & @CRLF & $s_Ret)

    [/autoit]
  • Danke für deinen Beitrag.

    Diese Alternative gibt mir die gleiche Anzahl der Elemente von dem Vortag wieder.
    Auf das Element genau.

    Um dies deutlicher auszudrücken:

    Vortag:154k
    Tag: 140k

    Ergebnis der Elemente in $s_Ret = 154k.

  • [autoit]

    _FileReadToArray(@ScriptDir & "\_Logs\Verzeichnisse\" & $final[0][1],$a_Array1)
    _FileReadToArray(@ScriptDir & "\_Logs\Verzeichnisse\" & $final[1][1], $a_Array2)

    [/autoit]
  • Bitte das ganze Skript - du wirst die Ergebnisse ja sicher kaum in der Msgbox ausgeben lassen.
    Der Code wie ich ihn gepostet habe kann im Maximum nur soviele Elemente erzeugen wie im 2. Array sind.
    Eine Anzahl darüber hinaus ist mit diesem Code gar nicht möglich.
    Da du sagst in $s_Ret stehen nun mehr Elemente als in $a_Array2 musst du noch etwas anderes verändert haben.

    Also bitte mal den kompletten Code und am besten die beiden Dateien mal auf z.B. >>ge.tt<< hochladen damit man das auch mal testen kann.

    Edit: Du solltest auch die richtige Länge des Arrays mit Ubound vergleichen anstatt nur $Array[0].
    Der Code wie ich ihn gepostet habe ist für 0-basierte Arrays und nicht für die merkwürdigen Arraykonstrukte bei denen die Elementanzahl im ersten Element steht.
    Du musst also schon noch die beiden Schleifen für 1-basierte Arrays abändern.

  • /Qcode quit.

    Die Dateien lade ich ungern hoch. Ist das komplette Filesystem des Notebooks meiner Firma ;)
    Am Besten erstellst du dir einfach die 2 Logs.

    Ändere aber vor dem 2ten log irgendetwas im Dateisystem ab. Wie zb. eine neue Datei erstellen.

    • Offizieller Beitrag

    Die Idee mit dem Scripting.Dictionary hatte ich auch. Nur habe ich gleich den Vergleich in beide Richtungen gemacht.
    Das dauert bei mir mit rund 35.000 Verzeichnissen nur ca. 1 Sekunde.

    Spoiler anzeigen
    [autoit]


    $sList1 = FileRead(@ScriptDir & '\list1.txt') ; alte Liste
    $aList1 = StringSplit($sList1, @CRLF, 1)

    [/autoit] [autoit][/autoit] [autoit]

    $oDictionary1 = ObjCreate('Scripting.Dictionary')
    $oDictionary1.CompareMode = 1

    [/autoit] [autoit][/autoit] [autoit]

    $sList2 = FileRead(@ScriptDir & '\list2.txt') ; neue Liste
    $aList2 = StringSplit($sList2, @CRLF, 1)

    [/autoit] [autoit][/autoit] [autoit]

    $oDictionary2 = ObjCreate('Scripting.Dictionary')
    $oDictionary2.CompareMode = 1

    [/autoit] [autoit][/autoit] [autoit]

    ConsoleWrite('-> Start! ' & StringFormat('%s:%s:%s.%s', @HOUR, @MIN, @SEC, @MSEC) & @CR)

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 1 To $aList1[0]
    $oDictionary1.Add($aList1[$i], 1)
    Next
    For $i = 1 To $aList2[0]
    $oDictionary2.Add($aList2[$i], 1)
    Next

    [/autoit] [autoit][/autoit] [autoit]

    ConsoleWrite('-> Dictionaries erstellt! ' & StringFormat('%s:%s:%s.%s', @HOUR, @MIN, @SEC, @MSEC) & @CR)

    [/autoit] [autoit][/autoit] [autoit]

    $sOut = ''
    For $i = 1 To $aList2[0]
    If Not $oDictionary1.Exists($aList2[$i]) Then $sOut &= $aList2[$i] & @CRLF
    Next
    For $i = 1 To $aList1[0]
    If Not $oDictionary2.Exists($aList1[$i]) Then $sOut &= $aList1[$i] & @CRLF
    Next

    [/autoit] [autoit][/autoit] [autoit]

    ConsoleWrite('-> Fertig! ' & StringFormat('%s:%s:%s.%s', @HOUR, @MIN, @SEC, @MSEC) & @CR)
    ClipPut($sOut)

    [/autoit]
  • !

    Danke :)