Need Help Remove Duplicate Values In Array ?

D

Dan Thompson

I have recently found a function on the interent that will remove duplicate
values within any array. It works just fine for a single dimensional array
but I would like to edit and change the code to work for Multi-Dimensional
array to support a minimum of 2 dimentional arrays. I only need it to find
any duplicate values within the first dimension of the array and than remove
any values corisponding to the same element number that the duplicate value
was found in the 1st dimention of the array and remove them from the 2nd and
3rd dimention of the array as well.

For example:
MyArray(1,2)
----------------------
| 0 | 0 | Hello |
| 1 | 0 | XX |
| 0 | 1 | Bye |
| 1 | 1 | YY |
| 0 | 2 | Hello |
| 1 | 2 | ZZ |
----------------------
So how it should work on the above sample array is that it would find look
for duplicate value in 1st dimention and find the value in 0,2 is a duplicate
of 0,0 and it will remove the 0,2 value and than since it found a duplicate
value in 0,2 and removed it, It would also than remove any value in same
corrisponding element row from the other dimentions i the case of the sample
above it would also not only remove 0,2 but it would remove 1,2 as well even
though 1,2 is not a duplicate
value.

Here is my currently working function based on just single dimetional arrays

Public Function RemoveDuplicates(ByRef SourceArray As Variant)
Dim Values As Collection
Dim Value As Variant
Dim Index1 As Long
Dim Index2 As Long

Set Values = New Collection
Index2 = LBound(SourceArray)
On Error Resume Next
For Index1 = LBound(SourceArray) To UBound(SourceArray)
Value = Empty
Value = Values(VarType(SourceArray(Index1)) & "|" & SourceArray(Index1))
If IsEmpty(Value) And Not Len(SourceArray(Index1)) = 0 Then
Values.Add SourceArray(Index1), VarType(SourceArray(Index1)) & "|"
& SourceArray(Index1)
SourceArray(Index2) = SourceArray(Index1)
Index2 = Index2 + 1
End If
Next Index1
On Error GoTo 0
If Index2 = 1 Then
SourceArray = Empty
Else
ReDim Preserve SourceArray(LBound(SourceArray) To Index2 - 1)
End If

End Function

I hope someone can help me find a solution.

Thanks,
Dan Thompson
 
D

Dave Peterson

So with this data, you'd end up with 2 rows:

----------------------
| 0 | 0 | Hello |
| 1 | 0 | XX |
----------------------

If that's correct, then this worked ok for me. I don't think it would scale for
more than 2 dimensions, though.

All I did was let each entry in the collection hold that row (an array).

Option Explicit
Sub testme()

'| 0 | 0 | Hello |
'| 1 | 0 | XX |
'| 0 | 1 | Bye |
'| 1 | 1 | YY |
'| 0 | 2 | Hello |
'| 1 | 2 | ZZ |

Dim myArr(0 To 5, 0 To 2) As Variant
Dim myArrCols(0 To 2) As Variant
Dim cCtr As Long
Dim rCtr As Long

Dim myColl As Collection
Dim ColCtr As Long

Dim myNewArr As Variant

'just creating the test array
myArrCols(0) = Array(0, 1, 0, 1, 0, 1)
myArrCols(1) = Array(0, 0, 1, 1, 2, 2)
myArrCols(2) = Array("hello", "xx", "bye", "yy", "hello", "zz")

For cCtr = LBound(myArrCols) To UBound(myArrCols)
For rCtr = LBound(myArrCols(cCtr)) To UBound(myArrCols(cCtr))
myArr(rCtr, cCtr) = myArrCols(cCtr)(rCtr)
Next rCtr
Next cCtr


'now the real work
Set myColl = New Collection

On Error Resume Next
For rCtr = LBound(myArr, 1) To UBound(myArr, 1)
myColl.Add Application.Index(myArr, rCtr + 1, 0), CStr(myArr(rCtr, 0))
Next rCtr
On Error GoTo 0

If myColl.Count = 0 Then
MsgBox "no data!"
Else
ReDim myNewArr(LBound(myArr, 1) _
To LBound(myArr, 1) + myColl.Count - 1, _
LBound(myArr, 2) To UBound(myArr, 2))

iCtr = 1
For rCtr = LBound(myNewArr, 1) To UBound(myNewArr, 1)
'this didn't work
'myNewArr(rCtr) = myColl.Item(iCtr)
'so I had to loop
ColCtr = 1
For cCtr = LBound(myNewArr, 2) To UBound(myNewArr, 2)
myNewArr(rCtr, cCtr) = myColl.Item(iCtr)(ColCtr)
ColCtr = ColCtr + 1
Next cCtr
iCtr = iCtr + 1
Next rCtr
End If

'and to prove that it worked ok
For rCtr = LBound(myNewArr, 1) To UBound(myNewArr, 1)
For cCtr = LBound(myNewArr, 2) To UBound(myNewArr, 2)
Debug.Print rCtr & "." & cCtr & ":" & myNewArr(rCtr, cCtr)
Next cCtr
Next rCtr

End Sub
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top