mvk25 Posted January 29, 2014 Posted January 29, 2014 I was trying to write a function to delete specific elements from an array using their indices and found a function made by Bowmore here . I modified the function to take an array of indices as input and to support 0-based and 1-based arrays. Here is the function along with an example: expandcollapse popup#AutoIt3Wrapper_Au3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6 -w- 7 #include <array.au3> ; #FUNCTION# ==================================================================================================================== ; Name...........: _ArrayDeleteIndices ; Description ...: This function is passed an array with the indices of the elements that need to be deleted from a given 1 or 2 ; dimensional array. The elements are deleted and the remaining elements are shifted up to take the empty spaces ; Syntax.........: _ArrayDeleteIndices(ByRef $avArray, Byref $aiIndices[, $iBase = Default]) ; Parameters ....: $$avArray - The 1 or 2 dimensional array to delete elements from ; $aiIndices - The 1 dimensional array containing the indices of elements to delete ; $iBase - If true then the arrays will be treated as 1 based. Default is 0 ; Return values .: Success - Returns 1 ; Failure - Returns 0 and sets @error to a non zero value ; @error 1 - If first parameter is not an array or an empty array ; 2 - If Indices parameter is not an array or an empty array ; 3 - If data array has more than 2 dimensions ; 4 - If indices array starts with a non integer value or -ve value ; 5 - $iBase is invalid ; 6 - Element 0 is in indices array but the array is 1-based! ; Author ........: (mvk25) ... Based on _ArrayRemoveBlanks by (Bowmore) ; [autoitscript.com/forum/topic/132027-array-delete-blank-element/?p=919764] ; Modified.......: ; Remarks .......: Relies on _ArraySort and _ArrayUnique from array.au3 UDF ; ; Related .......: _ArrayDelete ; Link ..........: ; Example .......: Yes ; =============================================================================================================================== Func _ArrayDeleteIndices(ByRef $avArray, ByRef $aiIndicesUnsrtd, $iBase = Default) ; Make sure $iBase is either 1 or 0 If $iBase = Default Then $iBase = 0 If $iBase < 0 Or $iBase > 1 Or (Not IsInt($iBase)) Then Return SetError(5, 0, 0) ; Check array parameters Local $aiArraySize[2] = [UBound($avArray)] If $aiArraySize[0] = $iBase Then Return SetError(1, 0, 0) If UBound($aiIndicesUnsrtd) = $iBase Then Return SetError(2, 0, 0) ; Get number of dimensions in data array and if more than 2 throw an error Local $iDims = UBound($avArray, 0) If $iDims > 2 Then Return SetError(3, 0, 0) ; Remove duplicate elements from the indices array Local $iColumn = 1, $iCase = 1, $iCountIn0Index = $iBase Local $aiIndices = _ArrayUnique($aiIndicesUnsrtd, $iColumn, $iBase, $iCase, $iCountIn0Index) ; Sort it ascendingly Local $iDescending = 0, $iSortStart = $iBase _ArraySort($aiIndices, $iDescending, $iSortStart) ; Check if array has a non integer or -ve element as first base element and return error If (Not IsInt($aiIndices[$iBase])) Or ($aiIndices[$iBase] < 0) Then Return SetError(4, 0, 0) ; Check if first base element is 0 when $iBase = 1 and return error If $iBase And $aiIndices[1] = 0 Then Return SetError(6, 0, 0) Local $iIndicesCount = UBound($aiIndices) Local $iIndex = $iBase Local $iIndexDel = $iBase $aiArraySize[1] = UBound($avArray, 2) For $i = $iBase To ($aiArraySize[0] - 1) If $i <> $aiIndices[$iIndexDel] Then For $j = 0 To ($aiArraySize[1] - 1) $avArray[$iIndex][$j] = $avArray[$i][$j] Next $iIndex += 1 Else If $iIndexDel < ($iIndicesCount - 1) Then $iIndexDel += 1 EndIf Next ReDim $avArray[$iIndex][$aiArraySize[1]] Return 1 EndFunc ;==>_ArrayDeleteIndices Example() Func Example() Local $iBase = 0 ; Make the test array 0 based or 1 based Local $iElements = 13 ; Number of elements in test array Local $iDims = 2 ; Number of columns in test array ; Create the array Local $aArray[$iElements + $iBase][$iDims] ; Fill the array with characters starting from A For $i = $iBase To ($iElements + $iBase - 1) For $j = 0 To ($iDims - 1) $aArray[$i][$j] = Chr(65 + $i - $iBase + $j) Next Next ; Now create the array containing the indices to be deleted from test array Local $iCase = 1 ; Try different arrays Switch $iCase Case 1 Local $aDel[] = [1, 3, 4, 11] Case 2 Local $aDel[] = [10, 5, 3, 2, 0] ; Order is not important Case 3 Local $aDel[] = [0, 5, 5, 1, 9, 9] ; Duplicate items are ignored Case 4 Local $aDel[] = [999, 0, 1000000] ; Items outside range are ignored Case 5 Local $aDel[] = [0, 10, -2] Case 6 Local $aDel[] = [3, 5, 6, 0] ; Try this with $iBase = 1 Case 7 Local $aDel[5] EndSwitch _ArrayDisplay($aArray, "Before") _ArrayDeleteIndices($aArray, $aDel, $iBase) If @error Then ConsoleWrite("!Error Code: " & @error & @LF & @LF) Else _ArrayDisplay($aArray, "After") EndIf EndFunc ;==>Example I need some feedback regarding the support 1-based arrays.
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now