Opened 15 years ago
Closed 15 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 15 years ago by UEZ
comment:2 Changed 15 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 15 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 15 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 15 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