Opened 14 years ago
Closed 14 years ago
#1806 closed Bug (No Bug)
$iBase in _ArrayUnique() not working properly
Reported by: | UEZ | Owned by: | |
---|---|---|---|
Milestone: | Component: | AutoIt | |
Version: | 3.3.6.1 | Severity: | None |
Keywords: | _ArrayUnique() 0-base 1-base | Cc: |
Description
#include <Array.au3> 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")
Should return a 0 based array but it doesn't because of line 1414 in Array.au3
-=> $aArrayTmp = StringSplit(StringTrimRight($sHold, StringLen($vDelim)), $vDelim, 1) ;Split the string into an array
Is working with line:
-=> $aArrayTmp = StringSplit(StringTrimRight($sHold, StringLen($vDelim)), $vDelim, 2 - $iBase)
but a $iBase check needs to be implemented before to avoid any numbers outside 0,1!
Br,
UEZ
Attachments (0)
Change History (5)
comment:1 Changed 14 years ago by UEZ
comment:2 Changed 14 years ago by UEZ
Here my try for the ArrayUnique function for up to 2D arrays:
; #FUNCTION# ==================================================================================================================== ; Name...........: ArrayUnique ; Description ...: Returns the Unique Elements of a 1-dimensional or 2-dimensional array. ; Syntax.........: _ArrayUnique($aArray[, $iBase = 0, oBase = 0, $iCase = 0]) ; Parameters ....: $aArray - The Array to use ; $iBase - [optional] Is the input Array 0-base or 1-base index. 0-base by default ; $oBase - [optional] Is the output 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 ; Return values .: Success - Returns a 1-dimensional or 2-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 - Array has more than 2 dimensions ; 3 - Array is already unique ; Remarks .......: Needs the function Max() ; Author ........: UEZ 2010 for 2D-array, Eukalyptus for 1D-array (modified by AspirinJunkie) ; Version .......: 0.90 Build 2010-11-10 Beta ; =============================================================================================================================== Func ArrayUnique($aArray, $iBase = 0, $oBase = 0, $iCase = 0) If Not IsArray($aArray) Then Return SetError(1, 0, 0) ;not an array If UBound($aArray, 0) > 2 Then Return SetError(2, 0, 0) ;array is greater than a 2D array If UBound($aArray) + $iBase = $iBase + 1 Then Return SetError(3, 0, $aArray) ;array is already unique Local $dim = UBound($aArray, 2), $i If $dim Then ;2D array Local $aUnique[2][$dim] Local $j, $k = $oBase, $sTemp, $sHold, $empty = 0 For $i = $iBase To UBound($aArray) - 1 For $j = 0 To $dim - 1 If $aArray[$i][$j] <> "" Then $sTemp &= $aArray[$i][$j] Else $empty += 1 EndIf Next If $empty < $dim Then $empty = 0 If Not StringInStr($sHold, $sTemp, $iCase) And Not $empty Then $sHold &= $sTemp For $j = 0 To $dim - 1 $aUnique[$k][$j] = $aArray[$i][$j] Next ReDim $aUnique[$k + 2][$dim] $k += 1 EndIf $sTemp = "" $empty = 0 Next ReDim $aUnique[UBound($aUnique) -1][$dim] If $oBase Then $aUnique[0][Max(UBound($aUnique, 0) - 2, 0)] = UBound($aUnique) - 1 Else ;1D array Local Static $oD = ObjCreate('Scripting.Dictionary') For $i In $aArray If Not $oD.Exists($i) Then $oD.Add($i, 0) Next Local $aUnique = $oD.Keys() $oD.RemoveAll EndIf Return SetError(0, 0, $aUnique) EndFunc Func Max($a, $b) If $a > $b Then Return $a Return $b EndFunc
I hope it is bug free ;-)
Br,
UEZ
comment:3 Changed 14 years ago by anonymous
Here an update of my ArrayUnique function (some bugs fixed):
; #FUNCTION# ===================================================================================================================== ; Name...........: ArrayUnique ; Description ...: Returns the Unique Elements of a 1-dimensional or 2-dimensional array. ; Syntax.........: _ArrayUnique($aArray[, $iBase = 0, oBase = 0, $iCase = 0]) ; Parameters ....: $aArray - The Array to use ; $iBase - [optional] Is the input Array 0-base or 1-base index. 0-base by default ; $oBase - [optional] Is the output 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 ; Return values .: Success - Returns a 1-dimensional or 2-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 - Array has more than 2 dimensions ; 3 - Array is already unique ; 4 - Scripting.Dictionary cannot be created for 1D array unique code ; Remarks .......: Needs the function Max() ; Author ........: UEZ 2010 for 2D-array, Eukalyptus for 1D-array (modified by AspirinJunkie) ; Version .......: 0.91 Build 2010-11-11 Beta ; ================================================================================================================================ Func ArrayUnique($aArray, $iBase = 0, $oBase = 0, $iCase = 0) If Not IsArray($aArray) Then Return SetError(1, 0, 0) ;not an array If UBound($aArray, 0) > 2 Then Return SetError(2, 0, 0) ;array is greater than a 2D array If UBound($aArray) + $iBase = $iBase + 1 Then Return SetError(3, 0, $aArray) ;array is already unique Local $dim = UBound($aArray, 2), $i If $dim Then ;2D array Local $aUnique[2][$dim] Local $j, $k = $oBase, $sTemp, $sHold, $empty = 0 For $i = $iBase To UBound($aArray) - 1 For $j = 0 To $dim - 1 If $aArray[$i][$j] <> "" Then $sTemp &= $aArray[$i][$j] Else $empty += 1 EndIf Next If $empty < $dim Then $empty = 0 $sTemp &= Chr(01) If Not StringInStr($sHold, $sTemp, $iCase) And Not $empty Then $sHold &= $sTemp For $j = 0 To $dim - 1 $aUnique[$k][$j] = $aArray[$i][$j] Next ReDim $aUnique[$k + 2][$dim] $k += 1 EndIf $sTemp = "" $empty = 0 Next ReDim $aUnique[UBound($aUnique) -1][$dim] If $oBase Then $aUnique[0][Max(UBound($aUnique, 0) - 2, 0)] = UBound($aUnique) - 1 Else ;1D array Local $oD = ObjCreate('Scripting.Dictionary') If @error Then Return SetError(4, 0, 0) For $i In $aArray If Not $oD.Exists($i) Then $oD.Add($i, 0) Next Local $aUnique = $oD.Keys() $oD.RemoveAll EndIf Return SetError(0, 0, $aUnique) EndFunc Func Max($a, $b) If $a > $b Then Return $a Return $b EndFunc
Br,
UEZ
comment:4 Changed 14 years ago by anonymous
Here my latest version:
; #FUNCTION# ============================================================================ ; Name.............: ArrayUnique ; Description ...: Returns the Unique Elements of a 1-dimensional or 2-dimensional array. ; Syntax...........: _ArrayUnique($aArray[, $iBase = 0, oBase = 0]) ; Parameters ...: $aArray - The Array to use ; $iBase - [optional] Is the input Array 0-base or 1-base index. 0-base by default ; $oBase - [optional] Is the output Array 0-base or 1-base index. 0-base by default ; Return values: Success - Returns a 1-dimensional or 2-dimensional array containing only the unique elements ; Failure - Returns 0 and Sets @Error: ; 0 - No error. ; 1 - Returns 0 if parameter is not an array. ; 2 - Array has more than 2 dimensions ; 3 - Array is already unique ; 4 - when source array is selected as one base but UBound(array) - 1 <> array[0] / array[0][0] ; 5 - Scripting.Dictionary cannot be created for 1D array unique code ; Author .........: UEZ 2010 for 2D-array, Yashied for 1D-array (modified by UEZ) ; Version ........: 0.96 Build 2010-11-20 Beta ; ======================================================================================= Func ArrayUnique($aArray, $iBase = 0, $oBase = 0) If Not IsArray($aArray) Then Return SetError(1, 0, 0) ;not an array If UBound($aArray, 0) > 2 Then Return SetError(2, 0, 0) ;array is greater than a 2D array If UBound($aArray) = $iBase + 1 Then Return SetError(3, 0, $aArray) ;array is already unique because of only 1 element Local $dim = UBound($aArray, 2), $i If $dim Then ;2D array If $iBase And UBound($aArray) - 1 <> $aArray[0][0] Then Return SetError(4, 0, 0) Local $oD = ObjCreate('Scripting.Dictionary') If @error Then Return SetError(5, 0, 0) Local $i, $j, $k = $oBase, $l, $s, $aTmp, $flag, $sSep = Chr(01) Local $aUnique[UBound($aArray)][$dim] If Not $oBase Then $flag = 2 For $i = $iBase To UBound($aArray) - 1 For $j = 0 To $dim - 1 $s &= $aArray[$i][$j] & $sSep Next If Not $oD.Exists($s) And StringLen($s) > 3 Then $oD.Add($s, $i) $aTmp = StringSplit(StringTrimRight($s, 1), $sSep, 2) For $l = 0 To $dim - 1 $aUnique[$k][$l] = $aTmp[$l] Next $k += 1 EndIf $s = "" Next $oD.RemoveAll $oD = "" If $k > 0 Then If $oBase Then $aUnique[0][0] = $k - 1 ReDim $aUnique[$k][$dim] Else ReDim $aUnique[1][$dim] EndIf Else ;1D array If $iBase And UBound($aArray) - 1 <> $aArray[0] Then Return SetError(4, 0, 0) Local $sData = '', $sSep = ChrW(160), $flag For $i = $iBase To UBound($aArray) - 1 If Not IsDeclared($aArray[$i] & '$') Then Assign($aArray[$i] & '$', 0, 1) $sData &= $aArray[$i] & $sSep EndIf Next If Not $oBase Then $flag = 2 Local $aUnique = StringSplit(StringTrimRight($sData, 1), $sSep, $flag) EndIf Return SetError(0, 0, $aUnique) EndFunc ;==>ArrayUnique
Is this something for you?
Br,
UEZ
comment:5 Changed 14 years ago by Jpm
- Resolution set to No Bug
- Status changed from new to closed
There is no error just use
Local $aArray[10] = [9, 2, 3, 4, 6, 1, 2, 3, 4, 6]
and play with the $iBase = 0 or 1
The remaining of the thread shoud go to a "new request" for 2D array support
Guidelines for posting comments:
- You cannot re-open a ticket but you may still leave a comment if you have additional information to add.
- In-depth discussions should take place on the forum.
For more information see the full version of the ticket guidelines here.
Seems _ArrayUnique() is also not working properly with 2D arrays!
Br,
UEZ