Sign in to follow this  
Followers 0
blindwig

_Array1MakeUnique()

1 post in this topic

#1 ·  Posted (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 by blindwig

Share this post


Link to post
Share on other sites



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 account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0