blindwig Posted July 27, 2005 Share Posted July 27, 2005 (edited) Sometimes I have an array which I need to remove duplicate items from. I have a duplicate-remover function that relies on being able to sort the array and pull out items that appear more than once. But the downfall is that the array is now sorted, which is unacceptable for arrays in which order of the elements is important. So I wrote a function to remove duplicate items in an array, and give the array back still in it's original order. Internally, it just creates a copy of the array and sorts that and then re-orders it back to the original order. That means it's a lot slower than a routine that returns a sorted array, but it has it's uses. Here's the code: CODE ;Function takes an array and removes all duplicate items. Upon return, array is in original order (not sorted) Func _Array1MakeUnique(ByRef $aIn, $iBase = 1, $CaseSense = 0) ;Check for proper input If UBound($aIn, 0) <> 1 Then SetError(1) Return 'This function only works on 1-d arrays' EndIf ;create a working array If $iBase Then $iBase = 1 $iInTop = $aIn[0] Else $iBase = 0 $iInTop = UBound($aIn) - 1 EndIf Local $aTemp[$iInTop + 2 - $iBase][2], $i For $i = $iBase To $iInTop $aTemp[0][0] = $aTemp[0][0] + 1 $aTemp[$aTemp[0][0]][0] = $aIn[$i] $aTemp[$aTemp[0][0]][1] = $i Next _ArraySort($aTemp, 0, 1, $aTemp[0][0], 2, 0) ;Remove duplicates from working array Local $Skip = 0 $i = $iBase While $i <= $aTemp[0][0] - $Skip ;Set $Skip to skip over duplicates ($Skip is an offset to copy (move) elements) While $i + $Skip + 1 <= $aTemp[0][0] And ((Not $CaseSense And $aTemp[$i][0] = $aTemp[$i + $Skip + 1][0]) Or ($CaseSense And $aTemp[$i][0] == $aTemp[$i + $Skip + 1][0])) ;Make sure you're using the earliest instance of the duplicate If $aTemp[$i][1] > $aTemp[$i + $Skip + 1][1] Then $aTemp[$i][0] = $aTemp[$i + $Skip + 1][0] $aTemp[$i][1] = $aTemp[$i + $Skip + 1][1] EndIf ;Increase $Skip to skip over this duplicate element $Skip = $Skip + 1 WEnd $i = $i + 1 If $Skip And $i + $Skip <= $aTemp[0][0] Then $aTemp[$i][0] = $aTemp[$i + $Skip][0] $aTemp[$i][1] = $aTemp[$i + $Skip][1] EndIf WEnd $aTemp[0][0] = $i - 1 ReDim $aTemp[$i][4] ;copy working array back to original array _ArraySort($aTemp, 0, 1, $aTemp[0][0], 2, 1) If $iBase Then ReDim $aIn[$aTemp[0][0] + 1] $aIn[0] = $aTemp[0][0] Else ReDim $aIn[$aTemp[0][0]] EndIf For $i = 1 To $aTemp[0][0] $aIn[$i - (1 -$iBase)] = $aTemp[$i][0] Next EndFunc Edited July 27, 2005 by blindwig My UDF Threads:Pseudo-Hash: Binary Trees, Flat TablesFiles: Filter by Attribute, Tree List, Recursive Find, Recursive Folders Size, exported to XMLArrays: Nested, Pull Common Elements, Display 2dSystem: Expand Environment Strings, List Drives, List USB DrivesMisc: Multi-Layer Progress Bars, Binary FlagsStrings: Find Char(s) in String, Find String in SetOther UDF Threads I Participated:Base64 Conversions Link to comment Share on other sites More sharing options...
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