Suggestions for checking that all array values are unique

Post

Posted
Rating:
#1 (In Topic #1222)
Avatar
Regular
thatbruce is in the usergroup ‘Regular’
 Hi all.

Looking for suggestions. My Integer[] must only contain unique values. I just can't think of a really good way that does not involve a lot of unnecessary statistical manipulations.

tia
b

Online now: No Back to the top

Post

Posted
Rating:
#2
Guru
BruceSteers is in the usergroup ‘Guru’

thatbruce said

Hi all.

Looking for suggestions. My Integer[] must only contain unique values. I just can't think of a really good way that does not involve a lot of unnecessary statistical manipulations.

tia
b

Off the top of my head I think just making a new list would be simplest….

Code (gambas)

  1.  
  2. Public sub Uniquify(aList as Integer[]) As Integer[]
  3.  
  4.   Dim aNewList As New Integer[]
  5.  
  6.   For c As Integer = 0 To aList.Max
  7.     If Not aNewList.Exist(aList[c]) Then aNewList.Add(aList[c])
  8.   Next
  9.  
  10.   Return aNewList
  11.  
  12.  
Online now: No Back to the top

Post

Posted
Rating:
#3
Avatar
Regular
thatbruce is in the usergroup ‘Regular’
Ta.

I wasn't clear enough. I just need to check it not replace it. So have gone with

Code (gambas)

  1.  
  2. Public Function CheckArrayUniqueness(aList as Integer[]) As Boolean
  3.  
  4.   Dim aNewList As New Integer[]
  5.  
  6.   For c As Integer = 0 To aList.Max
  7.     If Not aNewList.Exist(aList[c]) Then aNewList.Add(aList[c])
  8.   Next
  9.  
  10.   Return aNewList.Count = aList.Count
  11.  
  12.  

Anyone with other ideas? I feel that this is good enough as the length of the array is always < 25 items. But this will be called hundreds of times in a run, so I wonder if there is an efficiency weakness. I guess giving it a punt will give me some confidence.

b

Online now: No Back to the top

Post

Posted
Rating:
#4
Guru
BruceSteers is in the usergroup ‘Guru’

thatbruce said

Ta.

I wasn't clear enough. I just need to check it not replace it. So have gone with

Code (gambas)

  1.  
  2. Public Function CheckArrayUniqueness(aList as Integer[]) As Boolean
  3.  
  4.   Dim aNewList As New Integer[]
  5.  
  6.   For c As Integer = 0 To aList.Max
  7.     If Not aNewList.Exist(aList[c]) Then aNewList.Add(aList[c])
  8.   Next
  9.  
  10.   Return aNewList.Count = aList.Count
  11.  
  12.  

Anyone with other ideas? I feel that this is good enough as the length of the array is always < 25 items. But this will be called hundreds of times in a run, so I wonder if there is an efficiency weakness. I guess giving it a punt will give me some confidence.

b

aah i see well in that case probably be more efficient to finish checking and exit as soon as any duplicate is found rather than inspecting all the other items too.

Code (gambas)

  1.  
  2. Public Function CheckArrayUniqueness(aList as Integer[]) As Boolean
  3.  
  4.   Dim aNewList As New Integer[]
  5.  
  6.   For c As Integer = 0 To aList.Max
  7.     If aNewList.Exist(aList[c]) Then Return
  8.     aNewList.Add(aList[c])
  9.   Next
  10.  
  11.  
  12.  

Not sure how much more efficient it could be.
To ensure all are unique values you will have to inspect every element and make a note of every element inspected to match.

I tried another way, i thought to Sort the list first then any duplicates will be next to each other making searching simpler as can just check each item against the previous item and not build a new array..

Code (gambas)

  1. Public Function CheckArrayUniqueness2(aList As Integer[]) As Boolean
  2.  
  3.   Dim aNewList As Integer[] = aList.Copy().Sort()
  4.  
  5.   For c As Integer = 1 To aList.Max
  6.     If aNewList[c - 1] = aNewList[c] Then Return
  7.   Next
  8.  
  9.  
  10.  

with this code..

Code (gambas)

  1.  
  2.   Dim ai As New Integer[]
  3.   For c As Integer = 0 To 100
  4.    ai.Add(Rand(0, 100))
  5.   Next
  6.  
  7. Print CheckArrayUniqueness(ai)
  8. Print CheckArrayUniqueness2(ai)
  9.  
  10.  

The profiler says the second method is faster.
Online now: No Back to the top

Post

Posted
Rating:
#5
Avatar
Regular
thatbruce is in the usergroup ‘Regular’
Brilliant! (I think you might be getting a bit good with these prawns  ;) )

In fact I can do this all inline in my project as I sort the array just beforehand so I can check that it is monotonic.
This is all to do with an old problem regarding keeping two arrays synchronized. I have run it through the profiler here and this is around 3 times faster than my old "manual" way of handling that.

A beer or two for you the next time I'm on an island of note.

b

Online now: No Back to the top

Post

Posted
Rating:
#6
Avatar
Expert
Quincunxian is in the usergroup ‘Expert’
 If you want the check to fail on the first detection of a duplicate, it may be better to do the check with a loop/repeat rather than a For/next so that it drops as soon as it fails rather than running through the entire array.
It may shave off some more time in the process.

Cheers - Quin.
I code therefore I am
Online now: No Back to the top

Post

Posted
Rating:
#7
Guru
BruceSteers is in the usergroup ‘Guru’

Quincunxian said

If you want the check to fail on the first detection of a duplicate, it may be better to do the check with a loop/repeat rather than a For/next so that it drops as soon as it fails rather than running through the entire array.
It may shave off some more time in the process.

It does exit on first detection.. <EMOJI seq="1f60e" tseq="1f60e">😎</EMOJI>

  If aNewList[c - 1] = aNewList[c] Then Return
Online now: No Back to the top

Post

Posted
Rating:
#8
Avatar
Expert
Quincunxian is in the usergroup ‘Expert’
 Replied to an earlier version of the code  Doh.

Cheers - Quin.
I code therefore I am
Online now: No Back to the top
1 guest and 0 members have just viewed this.