Filter out duplicates with a map
Posted: Tue Nov 10, 2009 3:54 am
One of the useful attributes of a map is that it won't hold duplicate values. If you try to put a key into it that is identical to a key it already contains, the existing key will be replaced. Only one element of a given key will ever exist in the map. So it follows that if you have a dataset that contains duplicates and you want to filter the dupes out, you can just dump the whole thing in a map and voila - all the dupes are gone. All you're left with are the unique values. Forget about sorting, stepping through while checking for a new value, copying uniques to another array, all that fiddly stuff. This is like throwing the whole set at a wall and only the unique values will stick - the rest slide off. One practical example is counting the unique colors in a bitmap:
Code: Select all
Procedure CountColorsUsed(pBitmap)
GetObject_(pBitmap, SizeOf(BITMAP), @bmp.BITMAP)
*bmi.BITMAPINFO = AllocateMemory(SizeOf(BITMAPINFO)+SizeOf(RGBQUAD)*255)
With *bmi\bmiHeader
\biSize = SizeOf(BITMAPINFOHEADER)
\biWidth = bmp\bmWidth
\biHeight = bmp\bmHeight
\biPlanes = 1
\biBitCount = 32
EndWith
hDC = GetWindowDC_(#Null)
GetDIBits_(hDC, pBitmap, 0, bmp\bmHeight, #Null, *bmi, #DIB_RGB_COLORS)
Global *pPixels = AllocateMemory(*bmi\bmiHeader\biSizeImage)
iRes = GetDIBits_(hDC, pBitmap, 0, bmp\bmHeight, *pPixels, *bmi, #DIB_RGB_COLORS)
ReleaseDC_(#Null, hDC)
Global NewMap Colors(MemorySize(*pPixels)/2)
*p.long = *pPixels
For i=1 To MemorySize(*pPixels)/SizeOf(RGBQUAD)
Colors(Hex(*p\l)) = *p\l
*p+SizeOf(RGBQUAD)
Next
result = MapSize(colors())
ClearMap(colors())
FreeMemory(*pPixels)
FreeMemory(*bmi)
ProcedureReturn result
EndProcedure