Array Element anhand des Inhaltes löschen?

  • Hallo Com,

    Ich habe ein Array, in dem mehrere Web Adressen stehen.
    Nun habe ich in einem GUI eine Liste erstellt, und einen button

    Wenn man auf den Button klickt soll das asgewählte Element aus der Liste gelöscht werden.

    Hinterher das ganze am besten noch in eine .txt-Datei schrieben lassen, da am Anfang die Web Adressen dort auch ausgelesen werden.

    Bisjezt:

    Spoiler anzeigen
    [autoit]


    While 1
    Switch GUIGetMsg()
    Case $GUI_EVENT_CLOSE, $cancel, $cancel2
    GUISetState(@SW_HIDE)
    ExitLoop
    Case $delete, $delete2
    If GUICtrlRead($list) <> "" Then
    $realy_delete = MsgBox(260, "Suchmashinen Optimierer - Link Verwaltung", 'Möchten Sie den Link: "' & GUICtrlRead($list) & '" wirklich aus der Liste entfernen?')
    If $realy_delete = 6 Then
    $array = _ArrayBinarySearch($aRecords, GUICtrlRead($list))
    _ArrayDelete($aRecords, GUICtrlRead($list))
    EndIf
    Else
    MsgBox(0, "Suchmashinen Optimierer - Link Verwaltung", "Fehler - Bitte wählen Sie einen Link in der oberigen Liste aus.")
    EndIf
    EndSwitch
    WEnd

    [/autoit]

    So funktioniert das nur leider nicht, da man mit _ArrayDelete() eine Element nummer angeben muss, um dieses dann zu löschen.

    Ich möchte es aber so, das es per Inhalt gelöscht wird.

    Kann mir jemand helfen? Bzw. versteht ihr was ich meine?

    (Vielleicht gibt es ja acuh eine einfachere Methode, aber ich kenne gerade keine andere.)

    Einmal editiert, zuletzt von ophiel (15. November 2010 um 17:20)

  • [autoit]


    #include <Array.au3>
    Func _ArrayDeleteInhalt($array, $inhalt)
    $end = UBound($array) - 1
    $i = 0
    while true
    if $array[$i] = $inhalt then
    _ArrayDelete($array, $i)
    $i = $i - 1
    $end = $end - 1
    endif
    if $i = $end then
    ExitLoop
    endif
    $i = $i + 1
    wend
    return $array
    EndFunc

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

    Local $array[3] = ["Hallo", "Bye", "LoL"]
    $array = _ArrayDeleteInhalt($array, "Hallo")
    _ArrayDisplay($array)

    [/autoit]
  • Geht noch etwas fixer ;)

    [autoit]

    Func _ArrayDeleteInhalt(ByRef $array, $inhalt)
    For $i = Ubound($array) - 1 to 0 Step -1
    if $array[$i] = $inhalt then _ArrayDelete($array, $i)
    Next
    EndFunc

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

    Local $array[3] = ["Hallo", "Bye", "LoL"]
    $array = _ArrayDeleteInhalt($array, "Hallo")
    _ArrayDisplay($array)

    [/autoit]
  • Ach stimmt ^^
    Hatte ein Problem damit, dass wenn etwas gelöscht wird, die schleife am ende ein nichtmehr existierendes Element abrufen will ^^
    aber damit gehts natürlich besser

  • Wie kann man dieses besser schreiben?

    bekomme immer ne fehlermeldung

    Spoiler anzeigen
    [autoit]


    #include <Array.au3>
    #include <File.au3>

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

    Dim $aRecords
    _FileReadToArray(@ScriptDir &"\data\links.txt",$aRecords)

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

    _ArrayDisplay($aRecords)

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

    _ArrayDeleteInhalt($aRecords, "www.google.de")

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

    FileDelete(@ScriptDir &"\data\links.txt")
    FileWrite(@ScriptDir &"\data\links.txt", "")

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

    Dim $aRecords
    If $aRecords <> "" Then
    For $y = 1 to $aRecords[0]
    FileWriteLine(@ScriptDir &"\data\links.txt", $aRecords[$y])
    Next
    EndIf

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

    _ArrayDisplay($aRecords)

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

    Func _ArrayDeleteInhalt(ByRef $array, $inhalt)
    For $i = Ubound($array) - 1 to 0 Step -1
    if $array[$i] = $inhalt then _ArrayDelete($array, $i)
    Next
    EndFunc

    [/autoit]

    Fehler:

    Spoiler anzeigen
    Code
    G:\USB\AutoIT skripte\Vasco Shop Prg\Suchmaschinen Optimierer\test2.au3 (19) : ==> Array variable has incorrect number of subscripts or subscript dimension range exceeded.:
    FileWriteLine(@ScriptDir &"\data\links.txt", $aRecords[$y])
    FileWriteLine(@ScriptDir &"\data\links.txt", ^ ERROR
    ->14:27:19 AutoIT3.exe ended.rc:1
  • Ersetze mal

    [autoit]

    For $y = 1 to $aRecords[0]

    [/autoit]


    Durch:

    [autoit]

    For $y = 1 to UBound($aRecords) - 1

    [/autoit]
    • Offizieller Beitrag

    Soweit ich das sehe, ist die Löschfunktion nicht korrekt (führt aber nicht zum Fehler).
    Ansonsten solltest du dir mal: _FileWriteFromArray() anschauen.

    [autoit]


    Func _ArrayDeleteInhalt(ByRef $array, $inhalt)
    For $i = Ubound($array) - 1 to 1 Step -1
    If $array[$i] = $inhalt Then
    _ArrayDelete($array, $i)
    ExitLoop()
    EndIf
    Next
    EndFunc

    [/autoit]
  • Die Löschfunktion ist Korrekt. es ligt daran, dass er von 1 bis $array[0] geht.
    In Array 0 sollte die anzahl an elementen stehen, wenn aber eins gelöscht wurde ist die zahl in 0 fehlerhaft, weswegen der fehler kommt.
    Deswegen mit uBound arbeiten.

    • Offizieller Beitrag

    Die Löschfunktion ist Korrekt.


    ;) Vergleich mal meine Version mit deiner. Fällt dir was auf? Ist zwar nicht elementar, aber sinnlos: Du vergleichst auch das Element [0] - den Zähler. Außerdem ist es sinnvoll nach Erfolg die Schleife zu verlassen. Ausnahme: mehrfaches Vorkommen desselben Wertes ist möglich.
    Btw: Wenn du rückwärts iterierst, ist es völlig wurscht ob du als Startwert UBound($array)-1 oder $array[0] verwendest. Der jeweils aktive Index kann nicht wieder vorkommen, da heruntergezählt wird.

  • Nun, FALS in 0 der Zähler steht ^^
    Ich habe ubound benutzt, da er ja nicht zwangsweise in 0 steht. Und deswegen zähle ich auch bis 0 runter.
    Nur für diesen Zweck ist das natürlich richtig, aber die Funktion könnte man nicht in allen fällen anwenden.

    • Offizieller Beitrag

    Nun, FALS in 0 der Zähler steht ^^


    Es war ja auch keine allgemeine Falldiskussion, sondern eine auf einem Skriptbsp. basierende Frage. Somit stand außer Frage, dass der Zähler in [0] ist. Aber genug der Scharmützel - soll der Threadstarter erstmal seinen Senf dazugeben oder zufrieden sein. :rofl: