Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations bkrike on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Proper way to sort a Collection ??

Status
Not open for further replies.

fenris

Programmer
May 20, 1999
824
CA
What is the best way to sort a collection without screwing up the references and making a mess of things?


Say I have a collection made up of objects of a custom type called myObject.

myObject has 2 properties, myName and mySize

I want to be able to sort the collection called objCol by the mySize property into descending/asscending (doesn't matter which)

I want to do a simple bubble sort (as the collection, is not very large, 30 or so objects) but am having problems with the objects and their references.

here is the frame work that i have


dim i as long ,j as long , upper as long 'indices
dim myTempi as myObject
dim myTempj as myObject

upper = objCol.count

for i = 1 to upper - 1
set myTempi = objCol.item(i)
for j = i to upper
set myTempj = objCol.item(j)
if myTempi.mySize < myTempj.mySize then
'with a traditional array, I would assign
'one of the values to a temp variable in the
'swapping procedure. Unfortunately this doesn't
'seem to work right. I am thinking about trying
'to add the variables to a temporary collection
'then set it to the working collection. But for
'the life of me I can't seem to grasp the details,
' Any ideas would be appreciated
endif
next j

next i



Troy Williams B.Eng.
fenris@hotmail.com

 
This seems to work, can anybody point out a better way? How would i convert this to a faster sorting routine?





'===================================
'form code
Option Explicit

Dim col As New Collection

Private Sub Command1_Click()
Dim myTemp As clsMyObject
Dim i As Long, upper As Long
Dim upperbound As Long
Dim lowerbound As Long

upper = 15
upperbound = 1000
lowerbound = 1

For i = 1 To upper
Set myTemp = New clsMyObject
myTemp.Name = &quot;Name&quot; & i
Randomize
myTemp.Size = Int((upperbound - lowerbound + 1) * Rnd + lowerbound)
col.Add myTemp
Set myTemp = Nothing
Next i

Text1.Text = &quot;&quot;
For Each myTemp In col
Text1.Text = Text1.Text & &quot;Name: &quot; & myTemp.Name & &quot; Size: &quot; & myTemp.Size & vbNewLine
Next myTemp

Set myTemp = Nothing
End Sub

Private Sub Command2_Click()
Dim myTempi As clsMyObject
Dim myTempj As clsMyObject
Dim myTempx As clsMyObject
Dim i As Long, upper As Long, j As Long

upper = col.Count

For i = 1 To upper - 1
Set myTempi = col.Item(i)
For j = i + 1 To upper
Set myTempj = col.Item(j)
If myTempi.Size < myTempj.Size Then
Set myTempx = New clsMyObject
myTempi.cloneMe myTempx
myTempj.cloneMe myTempi
myTempx.cloneMe myTempj
End If
Set myTempj = Nothing
Set myTempx = Nothing
Next j
Set myTempi = Nothing
Next i

Text2.Text = &quot;&quot;
For Each myTempi In col
Text2.Text = Text2.Text & &quot;Name: &quot; & myTempi.Name & &quot; Size: &quot; & myTempi.Size & vbNewLine
Next myTempi

Set myTempi = Nothing
Set myTempj = Nothing
Set myTempx = Nothing
End Sub



'===================================
'class code
Option Explicit

Private myName As String
Private mySize As Long




Public Property Get Size() As Long
Size = mySize
End Property

Public Property Let Size(ByVal v As Long)
mySize = v
End Property

Public Property Get Name() As String
Name = myName
End Property

Public Property Let Name(ByVal s As String)
myName = s
End Property


Public Function cloneMe(ByRef s As clsMyObject) As clsMyObject
s.Name = myName
s.Size = mySize

Set cloneMe = s
End Function
Troy Williams B.Eng.
fenris@hotmail.com

 
' Sort an Index to the collection then rebuild collection.
' Not tested
Dim colTmp as Collection
Dim I as long
Dim J as long
Dim aryName() as string
Dim aryI() as long
Dim strHold as string
Dim lngHold as long
J = myCol.Count
if J > 0 then
' Build array to sort
Redim aryName(J-1)
Redim aryI(J-1)
For I = 1 to J
aryName(I-1) = mycol.Item(I).name
aryI(I-1) = I
Next
' Bubble sort
For I = 0 to Ubound(aryName) - 1
' Find least of I on up
For J = I + 1 to Ubound(aryName)
If aryName(I) > aryName(J) then
strHold = aryName(I)
aryName(I) = aryName(J)
aryName(J) = strHold
lngHold = aryI(I)
aryI(I) = aryI(J)
ary(J) = lngHold
end if
Next
Next
' Rebuild Collection
set colTmp = New Collection
For I = 0 to Ubound(aryI)
colTmp.Add Mycol.Item(aryI(I))
Next
set mycol = tmpCol
set tmpcol = nothing
End if
Compare Code (Text)
Generate Sort in VB or VBScript
 
Thanks for the feedback, I'll be sure to try it when I get home.....


Thanks Troy Williams B.Eng.
fenris@hotmail.com

 
Before and after allow you to specify a position relative to another item giving you a more guarenteed location. I have a vague memory of the order not being guarenteed to match the add sequence.
[tt]
' Rebuild Collection

set colTmp = New Collection
colTmp.Add Mycol.Item(aryI(0))
For I = 1 to Ubound(aryI)
colTmp.Add Mycol.Item(aryI(I)), after:=colTmp.Count
Next
[/tt]




Wil Mead
wmead@optonline.net

 
Sort as you add:
upper = 15
upperbound = 1000
lowerbound = 1

For i = 1 To upper
Set myTemp = New clsMyObject
myTemp.Name = &quot;Name&quot; & i
Randomize
myTemp.Size = Int((upperbound - lowerbound + 1) * Rnd + lowerbound)
If myTemp.Size >= col(col.Count).Size Then
col.Add myTemp
Else
For j = 1 To col.Count
If myTemp.Size < col(j).Size Then
col.Add myTemp,,j
Exit For
End If
Next
End If
Set myTemp = Nothing
Next i
Tim

Remember the KISS principle:
Keep It Simple, Stupid! :cool:
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top