Array Ergenisse nur 1 mal

  • Hey, ich weiss es gibt die Funktion _ArrayUnique, oder wie die auch immer heisst ;)
    Das Problem, dass dort der Eintrag 0 immer die Anzahl Strings zurücksendet.
    Kann ich das i-wie verhindern?

    Liebe Grüsse
    Fr34k

  • Schreib die Funktion um oder schreib dir gleich eine eigene.
    Beispiel:

    Spoiler anzeigen
    [autoit]

    Func _ArrayUnique2(Const ByRef $aA)
    Local Static $oD = ObjCreate('Scripting.Dictionary')
    For $i In $aA
    If Not $oD.Exists($i) Then $oD.Add($i, 0)
    Next
    Local $aR = $oD.Keys()
    $oD.RemoveAll
    Return $aR
    EndFunc

    [/autoit]

    Einmal editiert, zuletzt von AspirinJunkie (9. November 2010 um 20:50)

    • Offizieller Beitrag

    Einfach mit _ArrayDelete den 0. Eintrag löschen und gut ist.

  • Hier ein Workaround:

    [autoit]


    #include <Array.au3>
    Dim $aArray[10] = [1, 2, 3, 4, 5, 1, 2, 3, 4, 5]
    _ArrayDisplay($aArray, "$aArray")
    $aNewArray = _ArrayUnique($aArray) ;Using Default Parameters
    _ArrayDelete($aNewArray, 0)
    _ArrayDisplay($aNewArray, "$aNewArray represents the 1st Dimension of $aArray")

    [/autoit]

    Beispiel ist aus der Hilfe.

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • Wobei es durchaus sinnvoll und nützlich ist die Anzahl der Strings, also die Arraygröße in array[0] stehen zu haben. Ansonsten müsstest du ggf. bei Schleifen die das komplette Array abarbeiten sollen immer zuerst mit ubound() prüfen wie groß das Array ist, um rechtzeitig die Schleife zu verlassen. Ein weiterer Vorteil ist, dass Eintrag 1 den Index 1 hat und du nicht daran denken musst, dass das Array bei 0 anfängt wenn du einen bestimmten Eintrag aufrufen willst.

  • Warum ist Ubound() schlimm?
    Ansonsten vermeide ich auch so gut es geht solche Späße mit der Elementanzahl im ersten Element (hab so ich bisher auch nur bei AutoIt gesehen) da ich dann eine For-In-Schleife nutzen kann um alle Elemente durchzugehen. Das ist deutlich übersichtlicher als For-To
    Mit der Elementanzahl am Anfang ist das nicht machbar.

  • Ich habe mir mal die _ArrayUnique() Funktion genauer angeschaut und es sieht nach einem Bug aus:

    [autoit]


    ...
    If $sHold Then
    $aArrayTmp = StringSplit(StringTrimRight($sHold, StringLen($vDelim)), $vDelim, 1) ;Split the string into an array
    Return $aArrayTmp ;SmOke_N's version used to Return SetError(0, 0, 0)
    EndIf
    ...

    [/autoit]

    Der Fehler liegt an dem StringSplit(), sollte so aussehen:

    [autoit]


    $aArrayTmp = StringSplit(StringTrimRight($sHold, StringLen($vDelim)), $vDelim, 2 - $iBase) ;Split the string into an array

    [/autoit]

    Das Beispiel von oben:

    Spoiler anzeigen
    [autoit]


    #include <Array.au3>

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

    Dim $aArray[10] = [1, 2, 3, 4, 5, 1, 2, 3, 4, 5]
    _ArrayDisplay($aArray, "$aArray")
    $aNewArray = __ArrayUnique($aArray, 1, 0) ;Using Default Parameters
    _ArrayDisplay($aNewArray, "$aNewArray represents the 1st Dimension of $aArray")

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

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _ArrayUnique
    ; Description ...: Returns the Unique Elements of a 1-dimensional array.
    ; Syntax.........: _ArrayUnique($aArray[, $iDimension = 1[, $iBase = 0[, $iCase = 0[, $vDelim = "|"]]]])
    ; Parameters ....: $aArray - The Array to use
    ; $iDimension - [optional] The Dimension of the Array to use
    ; $iBase - [optional] Is the Array 0-base or 1-base index. 0-base by default
    ; $iCase - [optional] Flag to indicate if the operations should be case sensitive.
    ; 0 = not case sensitive, using the user's locale (default)
    ; 1 = case sensitive
    ; 2 = not case sensitive, using a basic/faster comparison
    ; $vDelim - [optional] One or more characters to use as delimiters. However, cannot forsee its usefullness
    ; Return values .: Success - Returns a 1-dimensional array containing only the unique elements of that Dimension
    ; Failure - Returns 0 and Sets @Error:
    ; 0 - No error.
    ; 1 - Returns 0 if parameter is not an array.
    ; 2 - _ArrayUnique failed for some other reason
    ; 3 - Array dimension is invalid, should be an integer greater than 0
    ; Author ........: SmOke_N
    ; Modified.......: litlmike
    ; Remarks .......: Returns an array, the first element ($array[0]) contains the number of strings returned, the remaining elements ($array[1], $array[2], etc.) contain the unique strings.
    ; Related .......: _ArrayMax, _ArrayMin
    ; Link ..........:
    ; Example .......: Yes
    ; ===============================================================================================================================
    Func __ArrayUnique($aArray, $iDimension = 1, $iBase = 0, $iCase = 0, $vDelim = "|")
    Local $iUboundDim
    ;$aArray used to be ByRef, but litlmike altered it to allow for the choosing of 1 Array Dimension, without altering the original array
    If $vDelim = "|" Then $vDelim = Chr(01) ; by SmOke_N, modified by litlmike
    If Not IsArray($aArray) Then Return SetError(1, 0, 0) ;Check to see if it is valid array

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

    ;Checks that the given Dimension is Valid
    If Not $iDimension > 0 Then
    Return SetError(3, 0, 0) ;Check to see if it is valid array dimension, Should be greater than 0
    Else
    ;If Dimension Exists, then get the number of "Rows"
    $iUboundDim = UBound($aArray, 1) ;Get Number of "Rows"
    If @error Then Return SetError(3, 0, 0) ;2 = Array dimension is invalid.

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

    ;If $iDimension Exists, And the number of "Rows" is Valid:
    If $iDimension > 1 Then ;Makes sure the Array dimension desired is more than 1-dimensional
    Local $aArrayTmp[1] ;Declare blank array, which will hold the dimension declared by user
    For $i = 0 To $iUboundDim - 1 ;Loop through "Rows"
    _ArrayAdd($aArrayTmp, $aArray[$i][$iDimension - 1]) ;$iDimension-1 to match Dimension
    Next
    _ArrayDelete($aArrayTmp, 0) ;Get rid of 1st-element which is blank
    Else ;Makes sure the Array dimension desired is 1-dimensional
    ;If Dimension Exists, And the number of "Rows" is Valid, and the Dimension desired is not > 1, then:
    ;For the Case that the array is 1-Dimensional
    If UBound($aArray, 0) = 1 Then ;Makes sure the Array is only 1-Dimensional
    Dim $aArrayTmp[1] ;Declare blank array, which will hold the dimension declared by user
    For $i = 0 To $iUboundDim - 1
    _ArrayAdd($aArrayTmp, $aArray[$i])
    Next
    _ArrayDelete($aArrayTmp, 0) ;Get rid of 1st-element which is blank
    Else ;For the Case that the array is 2-Dimensional
    Dim $aArrayTmp[1] ;Declare blank array, which will hold the dimension declared by user
    For $i = 0 To $iUboundDim - 1
    _ArrayAdd($aArrayTmp, $aArray[$i][$iDimension - 1]) ;$iDimension-1 to match Dimension
    Next
    _ArrayDelete($aArrayTmp, 0) ;Get rid of 1st-element which is blank
    EndIf
    EndIf
    EndIf

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

    Local $sHold ;String that holds the Unique array info
    For $iCC = $iBase To UBound($aArrayTmp) - 1 ;Loop Through array
    ;If Not the case that the element is already in $sHold, then add it
    If Not StringInStr($vDelim & $sHold, $vDelim & $aArrayTmp[$iCC] & $vDelim, $iCase) Then _
    $sHold &= $aArrayTmp[$iCC] & $vDelim
    Next
    If $sHold Then
    $aArrayTmp = StringSplit(StringTrimRight($sHold, StringLen($vDelim)), $vDelim, 2 - $iBase) ;Split the string into an array
    Return $aArrayTmp ;SmOke_N's version used to Return SetError(0, 0, 0)
    EndIf
    Return SetError(2, 0, 0) ;If the script gets this far, it has failed
    EndFunc ;==>_ArrayUnique

    [/autoit]


    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • öhm, ich weiss ned was ich dazu sagen soll^^ xD
    Ich kapiers ned^^

    Dass das ein Bug hat, hilft mir eigentlich wenig^^

    Lg

    • Offizieller Beitrag

    Warum benutzt du nicht einfach den Code von UEZ.

    [autoit]

    $aNewArray = _ArrayUnique($aArray) ;Using Default Parameters
    _ArrayDelete($aNewArray, 0)

    [/autoit]


    Ist nur 1 Befehl mehr und dein UniqueArray sieht aus wie es soll.

  • Hi!


    Ja gibt eine Möglichkeit Array #include die Funktion _ArrayUnique suchen und StrinSplit ändern !
    Oder rauskopieren und zu deinen Bedürfnissen anpassen.

    Lg Kleiner

  • Hallo Community,

    diese UDF _ArrayUnique() ist nicht nur möglicherweise buggy, wie UEZ bereits festgestellt hat, sondern auch grottenlangsam. Mit ein paar kleinen Änderungen habe ich die Ausführungszeit schon mal locker um den Faktor 50 verbessert, und ich könnte mir vorstellen, dass da noch mehr drin ist:

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>
    Dim $aNames[10] = ["Anton", "Berta", "Cäsar", "Dora", "Emil", "Friedrich", "Gustav", "Heinrich", "Ida", "Julius"]
    Dim $aUnique[1000]
    For $I = 0 To Ubound($aUnique) - 1
    $aUnique[$I] = $aNames[Random(0, 9, 1)]
    Next
    _ArrayDisplay($aUnique, "Vorher")
    Dim $T1 = 0, $T2 = 0
    For $I = 1 To 20
    $T = TimerInit()
    $aTemp1 = ___ArrayUnique($aUnique)
    $T1 += TimerDiff($T)
    $T = TimerInit()
    $aTemp2 = _ArrayUnique($aUnique)
    $T2 += TimerDiff($T)
    Next
    _ArrayDisplay($aTemp1, Round($T1) & " ms")
    _ArrayDisplay($aTemp2, Round($T2) & " ms")
    Exit

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

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _ArrayUnique
    ; Description ...: Returns the Unique Elements of a 1-dimensional array.
    ; Syntax.........: _ArrayUnique($aArray[, $iDimension = 1[, $iBase = 0[, $iCase = 0[, $vDelim = "|"]]]])
    ; Parameters ....: $aArray - The Array to use
    ; $iDimension - [optional] The Dimension of the Array to use
    ; $iBase - [optional] Is the Array 0-base or 1-base index. 0-base by default
    ; $iCase - [optional] Flag to indicate if the operations should be case sensitive.
    ; 0 = not case sensitive, using the user's locale (default)
    ; 1 = case sensitive
    ; 2 = not case sensitive, using a basic/faster comparison
    ; $vDelim - [optional] One or more characters to use as delimiters. However, cannot forsee its usefullness
    ; Return values .: Success - Returns a 1-dimensional array containing only the unique elements of that Dimension
    ; Failure - Returns 0 and Sets @Error:
    ; 0 - No error.
    ; 1 - Returns 0 if parameter is not an array.
    ; 2 - _ArrayUnique failed for some other reason
    ; 3 - Array dimension is invalid, should be an integer greater than 0
    ; Author ........: SmOke_N
    ; Modified.......: litlmike
    ; Remarks .......: Returns an array, the first element ($array[0]) contains the number of strings returned, the remaining elements ($array[1], $array[2], etc.) contain the unique strings.
    ; Related .......: _ArrayMax, _ArrayMin
    ; Link ..........:
    ; Example .......: Yes
    ; ===============================================================================================================================
    Func ___ArrayUnique($aArray, $iDimension = 1, $iBase = 0, $iCase = 0, $vDelim = "|")
    Local $iUboundDim
    ;$aArray used to be ByRef, but litlmike altered it to allow for the choosing of 1 Array Dimension, without altering the original array
    If $vDelim = "|" Then $vDelim = Chr(01) ; by SmOke_N, modified by litlmike
    If Not IsArray($aArray) Then Return SetError(1, 0, 0) ;Check to see if it is valid array

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

    ;Checks that the given Dimension is Valid
    If Not $iDimension > 0 Then
    Return SetError(3, 0, 0) ;Check to see if it is valid array dimension, Should be greater than 0
    Else
    ;If Dimension Exists, then get the number of "Rows"
    $iUboundDim = UBound($aArray, 1) ;Get Number of "Rows"
    If @error Then Return SetError(3, 0, 0) ;2 = Array dimension is invalid.
    ;Declare blank array, which will hold the dimension declared by user
    Local $aArrayTmp[$iUboundDim]
    ;If $iDimension Exists, And the number of "Rows" is Valid:
    If $iDimension > 1 Then ;Makes sure the Array dimension desired is more than 1-dimensional
    For $i = 0 To $iUboundDim - 1 ;Loop through "Rows"
    $aArrayTmp[$i] = $aArray[$i][$iDimension - 1] ;$iDimension-1 to match Dimension
    Next
    Else ;Makes sure the Array dimension desired is 1-dimensional
    ;If Dimension Exists, And the number of "Rows" is Valid, and the Dimension desired is not > 1, then:
    ;For the Case that the array is 1-Dimensional
    If UBound($aArray, 0) = 1 Then ;Makes sure the Array is only 1-Dimensional
    ;~ For $i = 0 To $iUboundDim - 1
    ;~ $aArrayTmp[$i] = $aArray[$i]
    ;~ Next
    $aArrayTmp = $aArray
    Else ;For the Case that the array is 2-Dimensional
    For $i = 0 To $iUboundDim - 1
    $aArrayTmp[$i] = $aArray[$i][$iDimension - 1] ;$iDimension-1 to match Dimension
    Next
    EndIf
    EndIf
    EndIf

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

    Local $sHold ;String that holds the Unique array info
    For $iCC = $iBase To UBound($aArrayTmp) - 1 ;Loop Through array
    ;If Not the case that the element is already in $sHold, then add it
    If Not StringInStr($vDelim & $sHold, $vDelim & $aArrayTmp[$iCC] & $vDelim, $iCase) Then _
    $sHold &= $aArrayTmp[$iCC] & $vDelim
    Next
    If $sHold Then
    $aArrayTmp = StringSplit(StringTrimRight($sHold, StringLen($vDelim)), $vDelim, 2 - $iBase) ;Split the string into an array
    Return $aArrayTmp ;SmOke_N's version used to Return SetError(0, 0, 0)
    EndIf
    Return SetError(2, 0, 0) ;If the script gets this far, it has failed
    EndFunc ;==>_ArrayUnique

    [/autoit]


    Gibt es noch mehr UDFs dieser Art?

    • Offizieller Beitrag

    @Großvater.

    Die Lösung von AspirinJunkie ist noch schneller, wenn auch nicht so flexiebel wie deine.
    Werde aber deine Funktion und die von AspirinJunkie archivieren, kann ich bestimmt mal gebrauchen. ;)

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>
    Dim $aNames[10] = ["Anton", "Berta", "Cäsar", "Dora", "Emil", "Friedrich", "Gustav", "Heinrich", "Ida", "Julius"]
    Dim $aUnique[1000]
    For $I = 0 To Ubound($aUnique) - 1
    $aUnique[$I] = $aNames[Random(0, 9, 1)]
    Next
    _ArrayDisplay($aUnique, "Vorher")
    Dim $T1 = 0, $T2 = 0
    For $I = 1 To 20
    $T = TimerInit()
    $aTemp1 = ___ArrayUnique($aUnique)
    $T1 += TimerDiff($T)
    $T = TimerInit()
    $aTemp2 = _ArrayUnique2($aUnique)
    $T2 += TimerDiff($T)
    Next
    _ArrayDisplay($aTemp1, Round($T1) & " ms")
    _ArrayDisplay($aTemp2, Round($T2) & " ms")
    Exit

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

    Func _ArrayUnique2(Const ByRef $aA)
    Local Static $oD = ObjCreate('Scripting.Dictionary')
    For $i In $aA
    If Not $oD.Exists($i) Then $oD.Add($i, 0)
    Next
    Local $aR = $oD.Keys()
    $oD.RemoveAll
    Return $aR
    EndFunc
    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _ArrayUnique
    ; Description ...: Returns the Unique Elements of a 1-dimensional array.
    ; Syntax.........: _ArrayUnique($aArray[, $iDimension = 1[, $iBase = 0[, $iCase = 0[, $vDelim = "|"]]]])
    ; Parameters ....: $aArray - The Array to use
    ; $iDimension - [optional] The Dimension of the Array to use
    ; $iBase - [optional] Is the Array 0-base or 1-base index. 0-base by default
    ; $iCase - [optional] Flag to indicate if the operations should be case sensitive.
    ; 0 = not case sensitive, using the user's locale (default)
    ; 1 = case sensitive
    ; 2 = not case sensitive, using a basic/faster comparison
    ; $vDelim - [optional] One or more characters to use as delimiters. However, cannot forsee its usefullness
    ; Return values .: Success - Returns a 1-dimensional array containing only the unique elements of that Dimension
    ; Failure - Returns 0 and Sets @Error:
    ; 0 - No error.
    ; 1 - Returns 0 if parameter is not an array.
    ; 2 - _ArrayUnique failed for some other reason
    ; 3 - Array dimension is invalid, should be an integer greater than 0
    ; Author ........: SmOke_N
    ; Modified.......: litlmike
    ; Remarks .......: Returns an array, the first element ($array[0]) contains the number of strings returned, the remaining elements ($array[1], $array[2], etc.) contain the unique strings.
    ; Related .......: _ArrayMax, _ArrayMin
    ; Link ..........:
    ; Example .......: Yes
    ; ===============================================================================================================================
    Func ___ArrayUnique($aArray, $iDimension = 1, $iBase = 0, $iCase = 0, $vDelim = "|")
    Local $iUboundDim
    ;$aArray used to be ByRef, but litlmike altered it to allow for the choosing of 1 Array Dimension, without altering the original array
    If $vDelim = "|" Then $vDelim = Chr(01) ; by SmOke_N, modified by litlmike
    If Not IsArray($aArray) Then Return SetError(1, 0, 0) ;Check to see if it is valid array

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

    ;Checks that the given Dimension is Valid
    If Not $iDimension > 0 Then
    Return SetError(3, 0, 0) ;Check to see if it is valid array dimension, Should be greater than 0
    Else
    ;If Dimension Exists, then get the number of "Rows"
    $iUboundDim = UBound($aArray, 1) ;Get Number of "Rows"
    If @error Then Return SetError(3, 0, 0) ;2 = Array dimension is invalid.
    ;Declare blank array, which will hold the dimension declared by user
    Local $aArrayTmp[$iUboundDim]
    ;If $iDimension Exists, And the number of "Rows" is Valid:
    If $iDimension > 1 Then ;Makes sure the Array dimension desired is more than 1-dimensional
    For $i = 0 To $iUboundDim - 1 ;Loop through "Rows"
    $aArrayTmp[$i] = $aArray[$i][$iDimension - 1] ;$iDimension-1 to match Dimension
    Next
    Else ;Makes sure the Array dimension desired is 1-dimensional
    ;If Dimension Exists, And the number of "Rows" is Valid, and the Dimension desired is not > 1, then:
    ;For the Case that the array is 1-Dimensional
    If UBound($aArray, 0) = 1 Then ;Makes sure the Array is only 1-Dimensional
    ;~ For $i = 0 To $iUboundDim - 1
    ;~ $aArrayTmp[$i] = $aArray[$i]
    ;~ Next
    $aArrayTmp = $aArray
    Else ;For the Case that the array is 2-Dimensional
    For $i = 0 To $iUboundDim - 1
    $aArrayTmp[$i] = $aArray[$i][$iDimension - 1] ;$iDimension-1 to match Dimension
    Next
    EndIf
    EndIf
    EndIf

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

    Local $sHold ;String that holds the Unique array info
    For $iCC = $iBase To UBound($aArrayTmp) - 1 ;Loop Through array
    ;If Not the case that the element is already in $sHold, then add it
    If Not StringInStr($vDelim & $sHold, $vDelim & $aArrayTmp[$iCC] & $vDelim, $iCase) Then _
    $sHold &= $aArrayTmp[$iCC] & $vDelim
    Next
    If $sHold Then
    $aArrayTmp = StringSplit(StringTrimRight($sHold, StringLen($vDelim)), $vDelim, 2 - $iBase) ;Split the string into an array
    Return $aArrayTmp ;SmOke_N's version used to Return SetError(0, 0, 0)
    EndIf
    Return SetError(2, 0, 0) ;If the script gets this far, it has failed
    EndFunc ;==>_ArrayUnique

    [/autoit]
  • Hi!


    Meine Version! ;)

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>
    Dim $aNames[10] = ["Anton", "Berta", "Cäsar", "Dora", "Emil", "Friedrich", "Gustav", "Heinrich", "Ida", "Julius"]
    ;Dim $aNames[10] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    Dim $aUnique[10000]
    For $I = 0 To UBound($aUnique) - 1
    $aUnique[$I] = $aNames[Random(0, 9, 1)]
    Next

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

    Dim $T1 = 0, $T2 = 0
    For $I = 1 To 20
    $T = TimerInit()
    $aTemp1 = ___ArrayUnique($aUnique)
    $T1 += TimerDiff($T)
    $T = TimerInit()
    $aTemp2 = _ArrayUnique2($aUnique)
    $T2 += TimerDiff($T)
    Next
    _ArrayDisplay($aTemp1, Round($T1) & " ms")
    _ArrayDisplay($aTemp2, Round($T2) & " ms")
    Exit

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

    Func _ArrayUnique2(Const ByRef $aA)
    Local Static $oD = ObjCreate('Scripting.Dictionary')
    For $I In $aA
    If Not $oD.Exists($I) Then $oD.Add($I, 0)
    Next
    Local $aR = $oD.Keys()
    $oD.RemoveAll
    Return $aR
    EndFunc ;==>_ArrayUnique2

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

    Func ___ArrayUnique(Const ByRef $aArray, $iDimension = 1, Const $iBase = 0, Const $iCase = 0, $vDelim = "|")
    If Not IsArray($aArray) Then Return SetError(1, 0, 0)
    If Not $iDimension Then Return SetError(3, 0, 0)
    If ($vDelim = '|') Then $vDelim = Chr(01)
    Local $iUboundDim = UBound($aArray)
    Local $sHold
    If (UBound($aArray, 0) = 1) Then
    For $I = $iBase To $iUboundDim - 1
    If Not StringInStr($sHold, $aArray[$I], $iCase) Then $sHold &= $aArray[$I] & $vDelim
    Next
    Else
    For $I = $iBase To $iUboundDim - 1
    If Not StringInStr($sHold, $aArray[$I][$iDimension - 1], $iCase) Then $sHold &= $aArray[$I][$iDimension - 1] & $vDelim
    Next
    EndIf
    If $sHold Then Return StringSplit(StringTrimRight($sHold, StringLen($vDelim)), $vDelim, 2)
    Return SetError(2, 0, 0)
    EndFunc ;==>___ArrayUnique

    [/autoit]

    Edit: wie gerade feststellen musste arbeitet die Angepaste Version nich einwandfrei bei Zahlen. :S

    Edit2: Haben den Bug gefunden Jetzt alles Gut :D

    Lg Kleiner

    4 Mal editiert, zuletzt von Kleiner (10. November 2010 um 16:17)

  • 2D Arrays scheinen auch nicht zu funzen:

    Spoiler anzeigen
    [autoit]


    #include <Array.au3>
    Dim $aNames[10][2] = [["Anton", 33], ["Berta", 15], ["Cäsar", 300], ["Dora", 24], ["Emil", 33], ["Friedrich", 57], ["Gustav", 53], ["Heinrich", 34], ["Ida", 13], ["Julius", 77]]
    Dim $aUnique[1000][2]
    For $I = 0 To Ubound($aUnique) - 1
    $r = Random(0, 9, 1)
    $aUnique[$I][0] = $aNames[$r][0]
    $aUnique[$I][1] = $aNames[$r][1]
    Next
    _ArrayDisplay($aUnique, "Vorher")
    Dim $T1 = 0, $T2 = 0
    For $I = 1 To 20
    $T = TimerInit()
    $aTemp1 = ___ArrayUnique($aUnique, 1, 1)
    $T1 += TimerDiff($T)
    $T = TimerInit()
    $aTemp2 = _ArrayUnique($aUnique, 1, 1)
    $T2 += TimerDiff($T)
    Next
    _ArrayDisplay($aTemp1, Round($T1) & " ms")
    _ArrayDisplay($aTemp2, Round($T2) & " ms")
    Exit

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

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _ArrayUnique
    ; Description ...: Returns the Unique Elements of a 1-dimensional array.
    ; Syntax.........: _ArrayUnique($aArray[, $iDimension = 1[, $iBase = 0[, $iCase = 0[, $vDelim = "|"]]]])
    ; Parameters ....: $aArray - The Array to use
    ; $iDimension - [optional] The Dimension of the Array to use
    ; $iBase - [optional] Is the Array 0-base or 1-base index. 0-base by default
    ; $iCase - [optional] Flag to indicate if the operations should be case sensitive.
    ; 0 = not case sensitive, using the user's locale (default)
    ; 1 = case sensitive
    ; 2 = not case sensitive, using a basic/faster comparison
    ; $vDelim - [optional] One or more characters to use as delimiters. However, cannot forsee its usefullness
    ; Return values .: Success - Returns a 1-dimensional array containing only the unique elements of that Dimension
    ; Failure - Returns 0 and Sets @Error:
    ; 0 - No error.
    ; 1 - Returns 0 if parameter is not an array.
    ; 2 - _ArrayUnique failed for some other reason
    ; 3 - Array dimension is invalid, should be an integer greater than 0
    ; Author ........: SmOke_N
    ; Modified.......: litlmike
    ; Remarks .......: Returns an array, the first element ($array[0]) contains the number of strings returned, the remaining elements ($array[1], $array[2], etc.) contain the unique strings.
    ; Related .......: _ArrayMax, _ArrayMin
    ; Link ..........:
    ; Example .......: Yes
    ; ===============================================================================================================================
    Func ___ArrayUnique($aArray, $iDimension = 1, $iBase = 0, $iCase = 0, $vDelim = "|")
    Local $iUboundDim
    ;$aArray used to be ByRef, but litlmike altered it to allow for the choosing of 1 Array Dimension, without altering the original array
    If $vDelim = "|" Then $vDelim = Chr(01) ; by SmOke_N, modified by litlmike
    If Not IsArray($aArray) Then Return SetError(1, 0, 0) ;Check to see if it is valid array

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

    ;Checks that the given Dimension is Valid
    If Not $iDimension > 0 Then
    Return SetError(3, 0, 0) ;Check to see if it is valid array dimension, Should be greater than 0
    Else
    ;If Dimension Exists, then get the number of "Rows"
    $iUboundDim = UBound($aArray, 1) ;Get Number of "Rows"
    If @error Then Return SetError(3, 0, 0) ;2 = Array dimension is invalid.
    ;Declare blank array, which will hold the dimension declared by user
    Local $aArrayTmp[$iUboundDim]
    ;If $iDimension Exists, And the number of "Rows" is Valid:
    If $iDimension > 1 Then ;Makes sure the Array dimension desired is more than 1-dimensional
    For $i = 0 To $iUboundDim - 1 ;Loop through "Rows"
    $aArrayTmp[$i] = $aArray[$i][$iDimension - 1] ;$iDimension-1 to match Dimension
    Next
    Else ;Makes sure the Array dimension desired is 1-dimensional
    ;If Dimension Exists, And the number of "Rows" is Valid, and the Dimension desired is not > 1, then:
    ;For the Case that the array is 1-Dimensional
    If UBound($aArray, 0) = 1 Then ;Makes sure the Array is only 1-Dimensional
    ;~ For $i = 0 To $iUboundDim - 1
    ;~ $aArrayTmp[$i] = $aArray[$i]
    ;~ Next
    $aArrayTmp = $aArray
    Else ;For the Case that the array is 2-Dimensional
    For $i = 0 To $iUboundDim - 1
    $aArrayTmp[$i] = $aArray[$i][$iDimension - 1] ;$iDimension-1 to match Dimension
    Next
    EndIf
    EndIf
    EndIf

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

    Local $sHold ;String that holds the Unique array info
    For $iCC = $iBase To UBound($aArrayTmp) - 1 ;Loop Through array
    ;If Not the case that the element is already in $sHold, then add it
    If Not StringInStr($vDelim & $sHold, $vDelim & $aArrayTmp[$iCC] & $vDelim, $iCase) Then _
    $sHold &= $aArrayTmp[$iCC] & $vDelim
    Next
    If $sHold Then
    $aArrayTmp = StringSplit(StringTrimRight($sHold, StringLen($vDelim)), $vDelim, 2 - $iBase) ;Split the string into an array
    Return $aArrayTmp ;SmOke_N's version used to Return SetError(0, 0, 0)
    EndIf
    Return SetError(2, 0, 0) ;If the script gets this far, it has failed
    EndFunc ;==>_ArrayUnique

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

    Func ____ArrayUnique(Const ByRef $aArray, $iDimension = 1, Const $iBase = 0, Const $iCase = 0, $vDelim = "|")
    If Not IsArray($aArray) Then Return SetError(1, 0, 0)
    If Not $iDimension Then Return SetError(3, 0, 0)
    If ($vDelim = '|') Then $vDelim = Chr(01)
    Local $iUboundDim = UBound($aArray)
    Local $sHold
    If (UBound($aArray, 0) = 1) Then
    For $I = $iBase To $iUboundDim - 1
    If Not StringInStr($sHold, $aArray[$I], $iCase) Then $sHold &= $aArray[$I] & $vDelim
    Next
    Else
    For $I = $iBase To $iUboundDim - 1
    If Not StringInStr($sHold, $aArray[$I][$iDimension - 1], $iCase) Then $sHold &= $aArray[$I][$iDimension - 1] & $vDelim
    Next
    EndIf
    If $sHold Then Return StringSplit(StringTrimRight($sHold, StringLen($vDelim)), $vDelim, 2)
    Return SetError(2, 0, 0)
    EndFunc ;==>___ArrayUnique

    [/autoit]


    Wenn ich Zeit finde, bastele ich an einer ArrayUnique Funktion.

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • Hi!

    UEZ
    Stimmt hast recht, bug behoben! ^^

    Spoiler anzeigen
    [autoit]

    Func ___ArrayUnique(Const ByRef $aArray, $iDimension = 0, Const $iBase = 0, Const $iCase = 0, $vDelim = "|")
    If Not IsArray($aArray) Then Return SetError(1, 0, 0)
    If ($iDimension > 2) Or ($iDimension < 0) Then Return SetError(3, 0, 0)
    If ($vDelim = '|') Then $vDelim = Chr(01)
    Local $iUboundDim = UBound($aArray)
    Local $sHold
    If Not UBound($aArray, 2) Then
    For $I = $iBase To $iUboundDim - 1
    If Not StringInStr($sHold, $aArray[$I], $iCase) Then $sHold &= $aArray[$I] & $vDelim
    Next
    Else
    For $I = $iBase To $iUboundDim - 1
    If Not StringInStr($sHold, $aArray[$I][$iDimension], $iCase) Then $sHold &= $aArray[$I][$iDimension] & $vDelim
    Next
    EndIf
    If $sHold Then Return StringSplit(StringTrimRight($sHold, StringLen($vDelim)), $vDelim, 2)
    Return SetError(2, 0, 0)
    EndFunc ;==>___ArrayUnique

    [/autoit]

    Lg Kleiner