ArrayUnique ohne Bug´s und Schneller

      ArrayUnique ohne Bug´s und Schneller

      Hi Leute!

      Duch den Post Array Ergenisse nur 1 mal sind UEZ ;) , Großvater und ich auf Bugs gestoßen und bemerkt das die Funktion ziemlich langsam ist !

      Basteln Basteln Fertig.

      Updat: Bug behoben dank an Großvater

      Neue Versaion ArrayUnique:
      Spoiler anzeigen

      AutoIt-Quellcode

      1. ; #FUNCTION# ====================================================================================================================
      2. ; Name...........: _ArrayUnique
      3. ; Description ...: Returns the Unique Elements of a 1-dimensional array.
      4. ; Syntax.........: _ArrayUnique($aArray[, $iDimension = 1[, $iBase = 0[, $iCase = 0[, $vDelim = "|"]]]])
      5. ; Parameters ....: $aArray - The Array to use
      6. ; $iDimension - [optional] The Dimension of the Array to use
      7. ; $iBase - [optional] Is the Array 0-base or 1-base index. 0-base by default
      8. ; $iCase - [optional] Flag to indicate if the operations should be case sensitive.
      9. ; 0 = not case sensitive, using the user's locale (default)
      10. ; 1 = case sensitive
      11. ; 2 = not case sensitive, using a basic/faster comparison
      12. ; $vDelim - [optional] One or more characters to use as delimiters. However, cannot forsee its usefullness
      13. ; $iFlag - flag = 0 (default), it acts each included in the delimiter character as a separator mark
      14. ; flag = 1, it is the entire separator string used as a separator mark
      15. ; flag = 2, turned off the return of the number in the first element. Thus, the array is 0-based.
      16. ; It has to be now UBound () the size of the array.
      17. ; Return values .: Success - Returns a 1-dimensional array containing only the unique elements of that Dimension
      18. ; Failure - Returns 0 and Sets @Error:
      19. ; 0 - No error.
      20. ; 1 - Returns 0 if parameter is not an array.
      21. ; 2 - Array dimension is invalid, should be an integer greater than 0
      22. ; Author ........: SmOke_N
      23. ; Modified.......: litlmike, [Kleiner & Großvater & UEZ (:.AutoIT.de.:)]
      24. ; Remarks .......:
      25. ; Related .......:
      26. ; Link ..........:
      27. ; Example .......: Yes
      28. ; ===============================================================================================================================
      29. Func __ArrayUnique(Const ByRef $aArray, $iDimension = 0, Const $iBase = 0, Const $iCase = 0, $vDelim = '|', Const $iFlag = 0)
      30. If Not IsArray($aArray) Or UBound($aArray, 0) > 2 Then Return SetError(1, 0, -1)
      31. If ($iFlag < 0 Or $iFlag > 2) Then Return SetError(3, 0, -2)
      32. If ($vDelim = '|' Or Not $vDelim) Then $vDelim = Chr(01)
      33. Local $iUboundDim = UBound($aArray)
      34. Local $sHold
      35. If Not UBound($aArray, 2) Then
      36. For $I = $iBase To $iUboundDim - 1
      37. If Not StringInStr($sHold & $vDelim, $vDelim & $aArray[$I] & $vDelim, $iCase) Then $sHold &= $vDelim & $aArray[$I]
      38. Next
      39. Else
      40. If ($iDimension > (UBound($aArray, 2) - 1) Or $iDimension < 0) Then Return SetError(3, 0, -2)
      41. For $I = $iBase To $iUboundDim - 1
      42. If Not StringInStr($sHold & $vDelim, $vDelim & $aArray[$I][$iDimension] & $vDelim, $iCase) Then $sHold &= $vDelim & $aArray[$I][$iDimension]
      43. Next
      44. EndIf
      45. If $sHold Then Return StringSplit(StringTrimLeft($sHold, StringLen($vDelim)), $vDelim, $iFlag)
      46. Return SetError(2, 0, 0)
      47. EndFunc ;==>__ArrayUnique


      Lg Kleiner
      Dateien
      • _ArrayUnique.au3

        (3,26 kB, 278 mal heruntergeladen, zuletzt: )

      Dieser Beitrag wurde bereits 11 mal editiert, zuletzt von „Kleiner“ ()

      Hi,

      prima Arbeit, Kleiner. :)

      Vllt solltest Du die überarbeitete Funktion dem Originalautor zukommen lassen ... ;)


      Gruß
      Greenhorn
      »Wir beschließen etwas, stellen das dann in den Raum und warten einige Zeit ab, was passiert.
      Wenn es dann kein großes Geschrei gibt und keine Aufstände, weil die meisten gar nicht begreifen,
      was da beschlossen wurde, dann machen wir weiter - Schritt für Schritt, bis es kein Zurück mehr gibt.«
      (Jean-Claude Juncker)
      Wer ist denn UZE? :P

      Spoiler anzeigen

      AutoIt-Quellcode

      1. #include <Array.au3>
      2. 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]]
      3. Dim $aUnique[1000][2]
      4. For $I = 0 To Ubound($aUnique) - 1
      5. $r = Random(0, 9, 1)
      6. $aUnique[$I][0] = $aNames[$r][0]
      7. $aUnique[$I][1] = $aNames[$r][1]
      8. Next
      9. $test2 = _ArrayUnique3($aUnique)
      10. _ArrayDisplay($test2)
      11. Func _ArrayUnique3(Const ByRef $aArray, $iDimension = 0, Const $iBase = 0, Const $iCase = 0, $vDelim = '|')
      12. If ($iDimension > 2) Or ($iDimension < 0) Then Return SetError(3, 0, -2)
      13. If Not IsArray($aArray) Then Return SetError(1, 0, -1)
      14. If ($vDelim = '|') Then $vDelim = Chr(01)
      15. Local $iUboundDim = UBound($aArray)
      16. Local $sHold
      17. If Not UBound($aArray, 2) Then
      18. For $I = $iBase To $iUboundDim - 1
      19. If Not StringInStr($sHold, $aArray[$I], $iCase) Then $sHold &= $aArray[$I] & $vDelim
      20. Next
      21. Else
      22. For $I = $iBase To $iUboundDim - 1
      23. If Not StringInStr($sHold, $aArray[$I][$iDimension], $iCase) Then $sHold &= $aArray[$I][$iDimension] & $vDelim
      24. Next
      25. EndIf
      26. If $sHold Then Return StringSplit(StringTrimRight($sHold, StringLen($vDelim)), $vDelim, 2)
      27. Return SetError(2, 0, 0)
      28. EndFunc


      Ich bekomme nur ein 1D Array zurück!

      Gruß,
      UEZ
      ¯\_(ツ)_/¯

      Spoiler anzeigen

      Funktionen: _GUICtrlMenu_CreateBitmap() v0.60 Build 2012-01-07 beta, _GUIImageList_AddBitmapEx() v0.80 Build 2011-11-05 Beta, nNumber v0.90 Build 2010-11-11 Beta, Process Info v0.35 Beta, File_Seeker v0.85 Build 2010-12-01 Beta, Get_Schtasks v0.90 build 2010-12-30 Beta, _WinAPI_SetWindowTitleIcon v0.96 Build 2012-06-03 Beta
      GDI: GDI+ Beispiele, Visualization: Analog Meter, Plasma Variante, Screensaver, Rotating Letters, (einige mehr GDI+ Beispiele ), GDI+ Image Rotator and Saver Build 2009-12-23, GDI+ Rotating Cubes, GDI+ Zoomer, GDI+ Visualizer Oscilloscope Farbrausch Build 2010-09-08, GDI+ Pixel Text Effect Beta Build 2010-10-21, GDI+ Simple Clock build 2011-04-06, GDI+ Buchstaben Rotation, GDI+ Perfect Illusion Build 2011-06-02
      Misc: Play Chip Sound from Memory, Simple Image Slideshow v1.0 Build 2011-04-30 Beta
      Progs: SIC2 v2.0.1 Build 2012-02-24 Beta inkl. GUI, Integer<=>Binary Converter v1.0 Build 2011-09-19, Fussball Chronograph v1.4 Build 2010-03-09, AutoIt Windows Screenshooter v1.77 Build 2014-02-18, Tiny URL Downloader v0.96 Build 2011-01-24, Head - Tail v0.65 Build 2011-03-15 Beta, Check Ping Status v1.05 Build 2014-09-19 Beta, Uptime v0.76 Build 2011-12-13, AD Tools, ISO Creator v1.16 build 2012-09-11 beta, File to Base64 String Code Generator v1.17 Build 2014-08-01
      Spiel: AUTOITEROIDS v1.019 Build 2012-07-30
      UDF: Write Text on Bitmap.au3 v0.92 Build 2011-05-28 Beta, ArrayUnique v0.96 Build 2010-11-20 Beta, Get_Image_Info v0.80 Build 2011-05-03 Beta, Shuffle_Array v0.50 build 2011-05-24 beta

      Habe auch mal was gebastelt:

      Spoiler anzeigen

      AutoIt-Quellcode

      1. #include <Array.au3>
      2. ;~ Dim $aNames[10][2] = [["Anton", ""], ["Berta", 15]]
      3. Dim $aNames[10] = ["Antonia", "Anton", "Cäsar", "Dora", "Emil", "Friedrich", "Gustav", "Heinrich", "Ida", "Julius"]
      4. Dim $aUnique[100000]
      5. For $I = 0 To Ubound($aUnique) - 1
      6. $r = Random(0, 9, 1)
      7. $aUnique[$I] = $aNames[$r]
      8. Next
      9. $ts = TimerInit()
      10. $test = ArrayUnique($aUnique)
      11. $te = TimerDiff($ts)
      12. ConsoleWrite(Round($te, 2) & " ms." & @CRLF)
      13. _ArrayDisplay($test)
      14. Dim $aNames[10][2] = [["Antonia", ""], ["Anton", ""], ["Cäsar", 300], ["Dora", 24], ["Emil", 33], ["Friedrich", 57], ["Gustav", 53], ["Heinrich", 34], ["Ida", 13], ["Julius", 77]]
      15. Dim $aUnique[100000][2]
      16. For $I = 0 To Ubound($aUnique) - 1
      17. $r = Random(0, 9, 1)
      18. $aUnique[$I][0] = $aNames[$r][0]
      19. $aUnique[$I][1] = $aNames[$r][1]
      20. Next
      21. $ts = TimerInit()
      22. $test = ArrayUnique($aUnique)
      23. $te = TimerDiff($ts)
      24. ConsoleWrite(Round($te, 2) & " ms." & @CRLF)
      25. _ArrayDisplay($test)
      26. ; #FUNCTION# =====================================================================================================================
      27. ; Name.............: ArrayUnique
      28. ; Description ...: Returns the Unique Elements of a 1-dimensional or 2-dimensional array.
      29. ; Syntax...........: _ArrayUnique($aArray[, $iBase = 0, oBase = 0, $iCase = 0])
      30. ; Parameters ...: $aArray - The Array to use
      31. ; $iBase - [optional] Is the input Array 0-base or 1-base index. 0-base by default
      32. ; $oBase - [optional] Is the output Array 0-base or 1-base index. 0-base by default
      33. ; $iCase - [optional] Flag to indicate if the operations should be case sensitive.
      34. ; 0 = not case sensitive, using the user's locale (default)
      35. ; 1 = case sensitive
      36. ; 2 = not case sensitive, using a basic/faster comparison
      37. ; Return values: Success - Returns a 1-dimensional or 2-dimensional array containing only the unique elements of that Dimension
      38. ; Failure - Returns 0 and Sets @Error:
      39. ; 0 - No error.
      40. ; 1 - Returns 0 if parameter is not an array.
      41. ; 2 - Array has more than 2 dimensions
      42. ; 3 - Array is already unique
      43. ; 4 - when source array is selected as one base but UBound(array) - 1 <> array[0] / array[0][0]
      44. ; 5 - Scripting.Dictionary cannot be created for 1D array unique code
      45. ; Author .........: UEZ 2010 for 2D-array, Yashied for 1D-array (modified by UEZ)
      46. ; Version ........: 0.96 Build 2010-11-20 Beta
      47. ; ================================================================================================================================
      48. Func ArrayUnique($aArray, $iBase = 0, $oBase = 0, $iCase = 0)
      49. If Not IsArray($aArray) Then Return SetError(1, 0, 0) ;not an array
      50. If UBound($aArray, 0) > 2 Then Return SetError(2, 0, 0) ;array is greater than a 2D array
      51. If UBound($aArray) = $iBase + 1 Then Return SetError(3, 0, $aArray) ;array is already unique because of only 1 element
      52. Local $dim = UBound($aArray, 2), $i
      53. If $dim Then ;2D array
      54. If $iBase And UBound($aArray) - 1 <> $aArray[0][0] Then Return SetError(4, 0, 0)
      55. Local $oD = ObjCreate('Scripting.Dictionary')
      56. If @error Then Return SetError(5, 0, 0)
      57. Local $i, $j, $k = $oBase, $l, $s, $aTmp, $flag, $sSep = Chr(01)
      58. Local $aUnique[UBound($aArray)][$dim]
      59. If Not $oBase Then $flag = 2
      60. For $i = $iBase To UBound($aArray) - 1
      61. For $j = 0 To $dim - 1
      62. $s &= $aArray[$i][$j] & $sSep
      63. Next
      64. If Not $oD.Exists($s) And StringLen($s) > 3 Then
      65. $oD.Add($s, $i)
      66. $aTmp = StringSplit(StringTrimRight($s, 1), $sSep, 2)
      67. For $l = 0 To $dim - 1
      68. $aUnique[$k][$l] = $aTmp[$l]
      69. Next
      70. $k += 1
      71. EndIf
      72. $s = ""
      73. Next
      74. $oD.RemoveAll
      75. If $k > 0 Then
      76. If $oBase Then $aUnique[0][0] = $k - 1
      77. ReDim $aUnique[$k][$dim]
      78. Else
      79. ReDim $aUnique[1][$dim]
      80. EndIf
      81. Else ;1D array
      82. If $iBase And UBound($aArray) - 1 <> $aArray[0] Then Return SetError(4, 0, 0)
      83. Local $sData = '', $sSep = ChrW(160), $flag
      84. For $i = $iBase To UBound($aArray) - 1
      85. If Not IsDeclared($aArray[$i] & '$') Then
      86. Assign($aArray[$i] & '$', 0, 1)
      87. $sData &= $aArray[$i] & $sSep
      88. EndIf
      89. Next
      90. If Not $oBase Then $flag = 2
      91. Local $aUnique = StringSplit(StringTrimRight($sData, 1), $sSep, $flag)
      92. EndIf
      93. Return SetError(0, 0, $aUnique)
      94. EndFunc ;==>ArrayUnique


      Sollte auch für 2D Arrays funzen!

      Gruß,
      UEZ
      Dateien
      ¯\_(ツ)_/¯

      Spoiler anzeigen

      Funktionen: _GUICtrlMenu_CreateBitmap() v0.60 Build 2012-01-07 beta, _GUIImageList_AddBitmapEx() v0.80 Build 2011-11-05 Beta, nNumber v0.90 Build 2010-11-11 Beta, Process Info v0.35 Beta, File_Seeker v0.85 Build 2010-12-01 Beta, Get_Schtasks v0.90 build 2010-12-30 Beta, _WinAPI_SetWindowTitleIcon v0.96 Build 2012-06-03 Beta
      GDI: GDI+ Beispiele, Visualization: Analog Meter, Plasma Variante, Screensaver, Rotating Letters, (einige mehr GDI+ Beispiele ), GDI+ Image Rotator and Saver Build 2009-12-23, GDI+ Rotating Cubes, GDI+ Zoomer, GDI+ Visualizer Oscilloscope Farbrausch Build 2010-09-08, GDI+ Pixel Text Effect Beta Build 2010-10-21, GDI+ Simple Clock build 2011-04-06, GDI+ Buchstaben Rotation, GDI+ Perfect Illusion Build 2011-06-02
      Misc: Play Chip Sound from Memory, Simple Image Slideshow v1.0 Build 2011-04-30 Beta
      Progs: SIC2 v2.0.1 Build 2012-02-24 Beta inkl. GUI, Integer<=>Binary Converter v1.0 Build 2011-09-19, Fussball Chronograph v1.4 Build 2010-03-09, AutoIt Windows Screenshooter v1.77 Build 2014-02-18, Tiny URL Downloader v0.96 Build 2011-01-24, Head - Tail v0.65 Build 2011-03-15 Beta, Check Ping Status v1.05 Build 2014-09-19 Beta, Uptime v0.76 Build 2011-12-13, AD Tools, ISO Creator v1.16 build 2012-09-11 beta, File to Base64 String Code Generator v1.17 Build 2014-08-01
      Spiel: AUTOITEROIDS v1.019 Build 2012-07-30
      UDF: Write Text on Bitmap.au3 v0.92 Build 2011-05-28 Beta, ArrayUnique v0.96 Build 2010-11-20 Beta, Get_Image_Info v0.80 Build 2011-05-03 Beta, Shuffle_Array v0.50 build 2011-05-24 beta

      Dieser Beitrag wurde bereits 10 mal editiert, zuletzt von „UEZ“ ()

      Hi!


      @UEZ hab natürlich dich gemeint :D !

      Wie Nuts schon Schreibt laut Funktion soll ein 1D Array zurückgegeben werden.
      Davon ab ich habe ein Funktion geschriebne _ObjektAr2DDubDel die das selbe macht , auch 2D Array´s u. ein Extra das noch Sortiert wird , nur allein die Idee der Funktion ( Algo) die hinter _ArrayUnique steckt finde ich sehr schön, das in dieser Funktion von den Autoren überflüssige abfragen und schleifen eingebaut wurden kann ich nicht nachvollziehen aber gute.

      Lg Kleiner
      Hallo Kleiner,

      etwas mehr Aufwand ist schon erforderlich und ein paar mehr Fehlerprüfungen sind auch nicht schlecht.

      Lass Deine Funktion mal mit diesem Beispiel laufen
      Spoiler anzeigen

      AutoIt-Quellcode

      1. #include <Array.au3>
      2. ;~ Dim $aNames[10][2] = [["Anton", ""], ["Berta", 15]]
      3. Dim $aNames[10][2] = [["Anton", ""], ["Berta", 15], ["Bert", 300], ["Dora", 24], ["Emil", 33], ["Friedrich", 57], ["Gustav", 53], ["Heinrich", 34], ["Ida", 13], ["Julius", 77]]
      4. Dim $aUnique[10000][2]
      5. For $I = 0 To Ubound($aUnique) - 1
      6. $r = Random(0, 9, 1)
      7. $aUnique[$I][0] = $aNames[$r][0]
      8. $aUnique[$I][1] = $aNames[$r][1]
      9. Next
      10. $test = ArrayUnique($aNames)
      11. ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $test = ' & $test & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
      12. _ArrayDisplay($test)
      und schau mal, was dem armen Bert passiert. ;)


      Ich habe Deiner Funktion deshalb noch ein paar Ergänzungen zukommen lassen und mich dabei bemüht, so nah wie möglich am Original zu bleiben:
      Spoiler anzeigen

      AutoIt-Quellcode

      1. ; #FUNCTION# ====================================================================================================================
      2. ; Name...........: _ArrayUnique
      3. ; Description ...: Returns the Unique Elements of a 1D or 2D array.
      4. ; Syntax.........: _ArrayUnique($aArray[, $iColumn = 1[, $iBase = 0[, $iCase = 0[, $vDelim = "|"]]]])
      5. ; Parameters ....: $aArray - The Array to use
      6. ; $iColumn - [optional] 1-based column index for the 2nd dimension of the Array to use
      7. ; $iBase - [optional] Is the Array 0-base or 1-base index. 0-base by default
      8. ; $iCase - [optional] Flag to indicate if the operations should be case sensitive.
      9. ; |0 = not case sensitive, using the user's locale (default)
      10. ; |1 = case sensitive
      11. ; |2 = not case sensitive, using a basic/faster comparison
      12. ; $vDelim - [optional] One or more characters to use as delimiters. However, cannot forsee its usefullness
      13. ; Return values .: Success - Returns a 1-dimensional array containing only the unique elements of that Dimension
      14. ; Failure - Returns 0 and Sets @Error:
      15. ; |1 - Array is not valid.
      16. ; |2 - _ArrayUnique failed for some other reason
      17. ; |3 - Column index is invalid, should be an integer greater than 0
      18. ; Author ........: SmOke_N
      19. ; Modified.......: litlmike, [Kleiner & Großvater & UEZ (:.AutoIT.de.:)]
      20. ; Remarks .......:
      21. ; Related .......:
      22. ; Link ..........:
      23. ; Example .......: Yes
      24. ; ===============================================================================================================================
      25. Func __ArrayUnique(Const ByRef $aArray, Const $iColumn = 1, Const $iBase = 0, Const $iCase = 0, $vDelim = '|')
      26. ;Check to see if it is valid array
      27. If Not IsArray($aArray) Or UBound($aArray, 0) > 2 Then Return SetError(1, 0, 0)
      28. ;Check to see if dimension is valid
      29. If UBound($aArray, 0) = 2 And ($iColumn < 1 Or $iColumn > UBound($aArray, 2)) Then Return SetError(3, 0, 0)
      30. If ($vDelim = '|') Then $vDelim = Chr(01) ; by SmOke_N, modified by litlmike
      31. Local $iRows = UBound($aArray) ;Number of rows in the array
      32. Local $iLen = StringLen($vDelim) ;Length of delimiter
      33. Local $sHold = $vDelim ;String that holds the Unique array info
      34. If UBound($aArray, 0) = 1 Then
      35. ; 1D array
      36. For $I = $iBase To $iRows - 1
      37. ;If Not the case that the element is already in $sHold, then add it
      38. If Not StringInStr($sHold, $vDelim & $aArray[$I] & $vDelim, $iCase) Then $sHold &= $aArray[$I] & $vDelim
      39. Next
      40. Else
      41. ; 2D array
      42. For $I = $iBase To $iRows - 1
      43. ;If Not the case that the element is already in $sHold, then add it
      44. If Not StringInStr($sHold, $vDelim & $aArray[$I][$iColumn - 1] & $vDelim, $iCase) Then $sHold &= $aArray[$I][$iColumn - 1] & $vDelim
      45. Next
      46. EndIf
      47. If StringLen($sHold) > $iLen Then Return StringSplit(StringMid($sHold, $iLen + 1, StringLen($sHold) - $iLen * 2), $vDelim, 2 - $iBase) ; <-- 2 - $iBase by UEZ
      48. Return SetError(2, 0, 0) ;If the script gets this far, it has failed
      49. EndFunc ;==>__ArrayUnique
      Der Großvater
      Hi!

      @Großvater
      Stimmt , alt so viel hättes du nicht machen brauchen, Eine Variable zu abfrage reicht - $vDelim ich habe noch $iFlag für die Entscheidung ob o. Ohne Counter.
      Ich frage mich $iBase zu nehmen, denn meines erachtens nach ist $iBase für den Startindex und nicht für die Entscheidung Counter oder nicht ?Fraglich?

      Danke dir geändert Post#1!

      Lg Kleiner
    autoit.de Webutation