ArrayList.Sort Question

  • Thread starter Thread starter Derek Martin
  • Start date Start date
D

Derek Martin

Hi there, I have been playing with sorting my arraylist and having some
troubles. Maybe just going about it wrong. My arraylist contains objects
and one of the members of the object is 'name.' I would like to sort the
arraylist based on object.name - is that possible?
Thanks!
Derek
 
You'll have to have your own comparer that implements the IComparer
interface. Here's an example:

Public Class TestClass
Private mName As String

Public Property Name() As String
Get
Return mName
End Get
Set(ByVal Value As String)
mName = Value
End Set
End Property
End Class

Public Class TestClassSort
Implements IComparer

Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer
Implements System.Collections.IComparer.Compare
Return String.Compare(DirectCast(x, TestClass).Name(), DirectCast(y,
TestClass).Name(), CompareMethod.Binary)
End Function
End Class

Private Sub TestSort()
Dim arr As New ArrayList
Dim o(2) As TestClass
o(0) = New TestClass
o(0).Name = "One"
o(1) = New TestClass
o(1).Name = "Two"
o(2) = New TestClass
o(2).Name = "Three"
arr.AddRange(o)
For i As Integer = 0 To arr.Count - 1
Console.WriteLine(DirectCast(arr.Item(i), TestClass).Name)
Next
arr.Sort(New TestClassSort)
For i As Integer = 0 To arr.Count - 1
Console.WriteLine(DirectCast(arr.Item(i), TestClass).Name)
Next
End Sub


hope that helps..
Imran.
 
Thank you both! I will investigate :-)

Derek



Imran Koradia said:
You'll have to have your own comparer that implements the IComparer
interface. Here's an example:

Public Class TestClass
Private mName As String

Public Property Name() As String
Get
Return mName
End Get
Set(ByVal Value As String)
mName = Value
End Set
End Property
End Class

Public Class TestClassSort
Implements IComparer

Public Function Compare(ByVal x As Object, ByVal y As Object) As
Integer
Implements System.Collections.IComparer.Compare
Return String.Compare(DirectCast(x, TestClass).Name(),
DirectCast(y,
TestClass).Name(), CompareMethod.Binary)
End Function
End Class

Private Sub TestSort()
Dim arr As New ArrayList
Dim o(2) As TestClass
o(0) = New TestClass
o(0).Name = "One"
o(1) = New TestClass
o(1).Name = "Two"
o(2) = New TestClass
o(2).Name = "Three"
arr.AddRange(o)
For i As Integer = 0 To arr.Count - 1
Console.WriteLine(DirectCast(arr.Item(i), TestClass).Name)
Next
arr.Sort(New TestClassSort)
For i As Integer = 0 To arr.Count - 1
Console.WriteLine(DirectCast(arr.Item(i), TestClass).Name)
Next
End Sub


hope that helps..
Imran.
 
Derek,

As alternative to the others (not saying that it is better), can you look at
the datatable, that has a defaultview (dataview) build in to sort very.

Cor
 
Hi Imran, I have been working on this and I think there might be an easier
way with my code and perhaps you can assist me!? The objects begin life as
an XML Document, retrieved from SharePoint:

Public Shared Function getorgs()
Dim orgslist As New ArrayList
...
sQuery.select = "/list[@id='" + global.Organizations + "']"

myRequest.dsQuery = sQuery
Try
Dim myqueryelement As String '"Eq", "And", "Or"
Dim myquerystring As String 'The <field refs....>

'HERE IS MY QUERY, I'd like to add the sort, by field
OrgName ASC if possible

myqueryelement = "Eq"
myquerystring = "<FieldRef
Name='ActiveFlag'/><Value>1</Value>"

Dim ndQuery As XmlElement =
xmlDoc.CreateElement(myqueryelement)
ndQuery.InnerXml = myquerystring
spQuery.Where = ndQuery
myRequest.dsQuery.Query = spQuery
Dim myNode As XmlNode = myStsAd.Query(myRequest)

Dim xmlread As XmlDocument = New XmlDocument
Dim reader_node As XmlNode
reader_node =
myNode.SelectSingleNode("descendant::Organizations")

Dim orgidnodelist As XmlNodeList =
reader_node.SelectNodes("descendant::ID")
Dim orgnamenodelist As XmlNodeList =
reader_node.SelectNodes("descendant::OrgName")
...
'AT THIS POINT, I'd like to have the XMLDocument in OrgName
ASC order, so that as I loop through, I can add them to my arraylist and it
be in the proper order
counter = orgnamenodelist.Count

For i = 0 To counter - 1
'loop and create object
Dim organization As New
orgsobjects(orgnamenodelist(i)....)
...
'Add it
orgslist.Add(organization)
Next
'Return the object arraylist of objects, which are already
sorted, cause hopefully in the XPATH somewhere, I can sort the XMLDocument
BEFORE I start creating objects
Return orgslist

Catch ex As Exception
End Try
End Function

Basically, from my comments, I'd like to sort the document BEFORE making the
objects and loading them into the arraylist, saving me the hassle...what do
you think???

Thank you!

Derek
 
Derek,

Unfortunately, I'm not too familiar with SharePoint neither am I very well
versed with XML. But here's just an idea: Can you make use of the
XPathExpression via the XPathNavigator (which can be created off the
XmlElement you already have)? It has a AddSort method which I would think
should be what you are looking for. Something like this:

Dim mdQuery As XmlElement = xmlDoc.CreateElement(myqueryelement)
Dim nav As XPathNavigator = mdQuery.CreateNavigator();
Dim strXPathExpr As String = ' your xpath expression..
Dim exp As XPathExpression = nav.Compile(xtrXPathExpr)
exp.AddSort(... 'sort by your field..

But again - I'm not sure if that would work. You would have better luck
trying in the XML/SharePoint groups:

microsoft.public.xml
microsof.public.sharepoint.portalserver
microsoft.public.sharepoint.teamservices
microsof.public.sharepoint.portalserver.development
microsoft.public.sharepoint.teamservices.caml


Sorry..hope that helps..
Imran.


Derek Martin said:
Hi Imran, I have been working on this and I think there might be an easier
way with my code and perhaps you can assist me!? The objects begin life
as an XML Document, retrieved from SharePoint:

Public Shared Function getorgs()
Dim orgslist As New ArrayList
...
sQuery.select = "/list[@id='" + global.Organizations + "']"

myRequest.dsQuery = sQuery
Try
Dim myqueryelement As String '"Eq", "And", "Or"
Dim myquerystring As String 'The <field refs....>

'HERE IS MY QUERY, I'd like to add the sort, by field
OrgName ASC if possible

myqueryelement = "Eq"
myquerystring = "<FieldRef
Name='ActiveFlag'/><Value>1</Value>"

Dim ndQuery As XmlElement =
xmlDoc.CreateElement(myqueryelement)
ndQuery.InnerXml = myquerystring
spQuery.Where = ndQuery
myRequest.dsQuery.Query = spQuery
Dim myNode As XmlNode = myStsAd.Query(myRequest)

Dim xmlread As XmlDocument = New XmlDocument
Dim reader_node As XmlNode
reader_node =
myNode.SelectSingleNode("descendant::Organizations")

Dim orgidnodelist As XmlNodeList =
reader_node.SelectNodes("descendant::ID")
Dim orgnamenodelist As XmlNodeList =
reader_node.SelectNodes("descendant::OrgName")
...
'AT THIS POINT, I'd like to have the XMLDocument in OrgName
ASC order, so that as I loop through, I can add them to my arraylist and
it be in the proper order
counter = orgnamenodelist.Count

For i = 0 To counter - 1
'loop and create object
Dim organization As New
orgsobjects(orgnamenodelist(i)....)
...
'Add it
orgslist.Add(organization)
Next
'Return the object arraylist of objects, which are already
sorted, cause hopefully in the XPATH somewhere, I can sort the XMLDocument
BEFORE I start creating objects
Return orgslist

Catch ex As Exception
End Try
End Function

Basically, from my comments, I'd like to sort the document BEFORE making
the objects and loading them into the arraylist, saving me the
hassle...what do you think???

Thank you!

Derek




Imran Koradia said:
You'll have to have your own comparer that implements the IComparer
interface. Here's an example:

Public Class TestClass
Private mName As String

Public Property Name() As String
Get
Return mName
End Get
Set(ByVal Value As String)
mName = Value
End Set
End Property
End Class

Public Class TestClassSort
Implements IComparer

Public Function Compare(ByVal x As Object, ByVal y As Object) As
Integer
Implements System.Collections.IComparer.Compare
Return String.Compare(DirectCast(x, TestClass).Name(),
DirectCast(y,
TestClass).Name(), CompareMethod.Binary)
End Function
End Class

Private Sub TestSort()
Dim arr As New ArrayList
Dim o(2) As TestClass
o(0) = New TestClass
o(0).Name = "One"
o(1) = New TestClass
o(1).Name = "Two"
o(2) = New TestClass
o(2).Name = "Three"
arr.AddRange(o)
For i As Integer = 0 To arr.Count - 1
Console.WriteLine(DirectCast(arr.Item(i), TestClass).Name)
Next
arr.Sort(New TestClassSort)
For i As Integer = 0 To arr.Count - 1
Console.WriteLine(DirectCast(arr.Item(i), TestClass).Name)
Next
End Sub


hope that helps..
Imran.
 
Thanks Imran, that is getting me in the right direction!
I tried this:

Dim nav As System.Xml.XPath.XPathNavigator = ndQuery.CreateNavigator()
Dim strXPathExpr As String = "/Organizations/Organization_Row/OrgName"
Dim exp As System.Xml.XPath.XPathExpression = nav.Compile(strXPathExpr)
exp.AddSort(".", System.Xml.XPath.XmlSortOrder.Ascending,
System.Xml.XPath.XmlCaseOrder.None, "", Xml.XPath.XmlDataType.Text)

This gets the names in the correct order, but it doesn't reorder the
original document...if I could get it to do that, all would be perfect! Any
further ideas? If not, I am grateful for the help and I will try my luck in
public.xml
:-)

Cheers,
Derek



Imran Koradia said:
Derek,

Unfortunately, I'm not too familiar with SharePoint neither am I very well
versed with XML. But here's just an idea: Can you make use of the
XPathExpression via the XPathNavigator (which can be created off the
XmlElement you already have)? It has a AddSort method which I would think
should be what you are looking for. Something like this:

Dim mdQuery As XmlElement = xmlDoc.CreateElement(myqueryelement)
Dim nav As XPathNavigator = mdQuery.CreateNavigator();
Dim strXPathExpr As String = ' your xpath expression..
Dim exp As XPathExpression = nav.Compile(xtrXPathExpr)
exp.AddSort(... 'sort by your field..

But again - I'm not sure if that would work. You would have better luck
trying in the XML/SharePoint groups:

microsoft.public.xml
microsof.public.sharepoint.portalserver
microsoft.public.sharepoint.teamservices
microsof.public.sharepoint.portalserver.development
microsoft.public.sharepoint.teamservices.caml


Sorry..hope that helps..
Imran.


Derek Martin said:
Hi Imran, I have been working on this and I think there might be an
easier way with my code and perhaps you can assist me!? The objects
begin life as an XML Document, retrieved from SharePoint:

Public Shared Function getorgs()
Dim orgslist As New ArrayList
...
sQuery.select = "/list[@id='" + global.Organizations +
"']"

myRequest.dsQuery = sQuery
Try
Dim myqueryelement As String '"Eq", "And", "Or"
Dim myquerystring As String 'The <field refs....>

'HERE IS MY QUERY, I'd like to add the sort, by field
OrgName ASC if possible

myqueryelement = "Eq"
myquerystring = "<FieldRef
Name='ActiveFlag'/><Value>1</Value>"

Dim ndQuery As XmlElement =
xmlDoc.CreateElement(myqueryelement)
ndQuery.InnerXml = myquerystring
spQuery.Where = ndQuery
myRequest.dsQuery.Query = spQuery
Dim myNode As XmlNode = myStsAd.Query(myRequest)

Dim xmlread As XmlDocument = New XmlDocument
Dim reader_node As XmlNode
reader_node =
myNode.SelectSingleNode("descendant::Organizations")

Dim orgidnodelist As XmlNodeList =
reader_node.SelectNodes("descendant::ID")
Dim orgnamenodelist As XmlNodeList =
reader_node.SelectNodes("descendant::OrgName")
...
'AT THIS POINT, I'd like to have the XMLDocument in
OrgName ASC order, so that as I loop through, I can add them to my
arraylist and it be in the proper order
counter = orgnamenodelist.Count

For i = 0 To counter - 1
'loop and create object
Dim organization As New
orgsobjects(orgnamenodelist(i)....)
...
'Add it
orgslist.Add(organization)
Next
'Return the object arraylist of objects, which are already
sorted, cause hopefully in the XPATH somewhere, I can sort the
XMLDocument BEFORE I start creating objects
Return orgslist

Catch ex As Exception
End Try
End Function

Basically, from my comments, I'd like to sort the document BEFORE making
the objects and loading them into the arraylist, saving me the
hassle...what do you think???

Thank you!

Derek




Imran Koradia said:
You'll have to have your own comparer that implements the IComparer
interface. Here's an example:

Public Class TestClass
Private mName As String

Public Property Name() As String
Get
Return mName
End Get
Set(ByVal Value As String)
mName = Value
End Set
End Property
End Class

Public Class TestClassSort
Implements IComparer

Public Function Compare(ByVal x As Object, ByVal y As Object) As
Integer
Implements System.Collections.IComparer.Compare
Return String.Compare(DirectCast(x, TestClass).Name(),
DirectCast(y,
TestClass).Name(), CompareMethod.Binary)
End Function
End Class

Private Sub TestSort()
Dim arr As New ArrayList
Dim o(2) As TestClass
o(0) = New TestClass
o(0).Name = "One"
o(1) = New TestClass
o(1).Name = "Two"
o(2) = New TestClass
o(2).Name = "Three"
arr.AddRange(o)
For i As Integer = 0 To arr.Count - 1
Console.WriteLine(DirectCast(arr.Item(i), TestClass).Name)
Next
arr.Sort(New TestClassSort)
For i As Integer = 0 To arr.Count - 1
Console.WriteLine(DirectCast(arr.Item(i), TestClass).Name)
Next
End Sub


hope that helps..
Imran.


Hi there, I have been playing with sorting my arraylist and having some
troubles. Maybe just going about it wrong. My arraylist contains
objects
and one of the members of the object is 'name.' I would like to sort
the
arraylist based on object.name - is that possible?
Thanks!
Derek
 
Derek,

Apologies for the late reply. As I said, I'm not too familiar with XML
stuff. If you still haven't got that to work, I would suggest you ask this
in one of the xml groups. They should definitely help you solve this. Good
Luck !

Imran.


Derek Martin said:
Thanks Imran, that is getting me in the right direction!
I tried this:

Dim nav As System.Xml.XPath.XPathNavigator = ndQuery.CreateNavigator()
Dim strXPathExpr As String = "/Organizations/Organization_Row/OrgName"
Dim exp As System.Xml.XPath.XPathExpression = nav.Compile(strXPathExpr)
exp.AddSort(".", System.Xml.XPath.XmlSortOrder.Ascending,
System.Xml.XPath.XmlCaseOrder.None, "", Xml.XPath.XmlDataType.Text)

This gets the names in the correct order, but it doesn't reorder the
original document...if I could get it to do that, all would be perfect! Any
further ideas? If not, I am grateful for the help and I will try my luck in
public.xml
:-)

Cheers,
Derek



Imran Koradia said:
Derek,

Unfortunately, I'm not too familiar with SharePoint neither am I very well
versed with XML. But here's just an idea: Can you make use of the
XPathExpression via the XPathNavigator (which can be created off the
XmlElement you already have)? It has a AddSort method which I would think
should be what you are looking for. Something like this:

Dim mdQuery As XmlElement = xmlDoc.CreateElement(myqueryelement)
Dim nav As XPathNavigator = mdQuery.CreateNavigator();
Dim strXPathExpr As String = ' your xpath expression..
Dim exp As XPathExpression = nav.Compile(xtrXPathExpr)
exp.AddSort(... 'sort by your field..

But again - I'm not sure if that would work. You would have better luck
trying in the XML/SharePoint groups:

microsoft.public.xml
microsof.public.sharepoint.portalserver
microsoft.public.sharepoint.teamservices
microsof.public.sharepoint.portalserver.development
microsoft.public.sharepoint.teamservices.caml


Sorry..hope that helps..
Imran.


Derek Martin said:
Hi Imran, I have been working on this and I think there might be an
easier way with my code and perhaps you can assist me!? The objects
begin life as an XML Document, retrieved from SharePoint:

Public Shared Function getorgs()
Dim orgslist As New ArrayList
...
sQuery.select = "/list[@id='" + global.Organizations +
"']"

myRequest.dsQuery = sQuery
Try
Dim myqueryelement As String '"Eq", "And", "Or"
Dim myquerystring As String 'The <field refs....>

'HERE IS MY QUERY, I'd like to add the sort, by field
OrgName ASC if possible

myqueryelement = "Eq"
myquerystring = "<FieldRef
Name='ActiveFlag'/><Value>1</Value>"

Dim ndQuery As XmlElement =
xmlDoc.CreateElement(myqueryelement)
ndQuery.InnerXml = myquerystring
spQuery.Where = ndQuery
myRequest.dsQuery.Query = spQuery
Dim myNode As XmlNode = myStsAd.Query(myRequest)

Dim xmlread As XmlDocument = New XmlDocument
Dim reader_node As XmlNode
reader_node =
myNode.SelectSingleNode("descendant::Organizations")

Dim orgidnodelist As XmlNodeList =
reader_node.SelectNodes("descendant::ID")
Dim orgnamenodelist As XmlNodeList =
reader_node.SelectNodes("descendant::OrgName")
...
'AT THIS POINT, I'd like to have the XMLDocument in
OrgName ASC order, so that as I loop through, I can add them to my
arraylist and it be in the proper order
counter = orgnamenodelist.Count

For i = 0 To counter - 1
'loop and create object
Dim organization As New
orgsobjects(orgnamenodelist(i)....)
...
'Add it
orgslist.Add(organization)
Next
'Return the object arraylist of objects, which are already
sorted, cause hopefully in the XPATH somewhere, I can sort the
XMLDocument BEFORE I start creating objects
Return orgslist

Catch ex As Exception
End Try
End Function

Basically, from my comments, I'd like to sort the document BEFORE making
the objects and loading them into the arraylist, saving me the
hassle...what do you think???

Thank you!

Derek




You'll have to have your own comparer that implements the IComparer
interface. Here's an example:

Public Class TestClass
Private mName As String

Public Property Name() As String
Get
Return mName
End Get
Set(ByVal Value As String)
mName = Value
End Set
End Property
End Class

Public Class TestClassSort
Implements IComparer

Public Function Compare(ByVal x As Object, ByVal y As Object) As
Integer
Implements System.Collections.IComparer.Compare
Return String.Compare(DirectCast(x, TestClass).Name(),
DirectCast(y,
TestClass).Name(), CompareMethod.Binary)
End Function
End Class

Private Sub TestSort()
Dim arr As New ArrayList
Dim o(2) As TestClass
o(0) = New TestClass
o(0).Name = "One"
o(1) = New TestClass
o(1).Name = "Two"
o(2) = New TestClass
o(2).Name = "Three"
arr.AddRange(o)
For i As Integer = 0 To arr.Count - 1
Console.WriteLine(DirectCast(arr.Item(i), TestClass).Name)
Next
arr.Sort(New TestClassSort)
For i As Integer = 0 To arr.Count - 1
Console.WriteLine(DirectCast(arr.Item(i), TestClass).Name)
Next
End Sub


hope that helps..
Imran.


Hi there, I have been playing with sorting my arraylist and having some
troubles. Maybe just going about it wrong. My arraylist contains
objects
and one of the members of the object is 'name.' I would like to sort
the
arraylist based on object.name - is that possible?
Thanks!
Derek
 
Imran,

And not one answer on my simple solution, even not tried, what is in my
opinion so simple to make with a XML document just by itterating through the
nodereader.

:-)

Cor
 
Cor, do you mean create my own sorter by iterating? It has been many moons
since I last did a bubble sort or anything like it in code. Do you have
idea?

Thanks!
Derek
 
Derek,

When you see in this thread my message bellow than you see, as alternative
too the others that you can use a datatatable.

Because the structure looks often very much the same as an XMLdoc it is in
my opinion easy to fill using looping through an XML document using the
nodereader methode from the xmldocument.

Than a dataview on that table and use the sort property and all is done.

\\\\
Dim xmlString As String = "<department>" & _
"<employee name=""ABC"" age=""31"" sex=""male""/>" & _
"<employee name=""CDE"" age=""40"" sex=""male""/></department>"
Dim sr As New System.IO.StringReader(xmlString)
Dim doc As New Xml.XmlDocument
doc.Load(sr)
'or just in this case doc.LoadXML(xmlString)
Dim reader As New Xml.XmlNodeReader(doc)
While reader.Read()
Select Case reader.NodeType
Case Xml.XmlNodeType.Element
If reader.Name = "employee" Then
MessageBox.Show(reader.GetAttribute("name"))
End If
End Select
End While
///

I thought that I had once seen a methode that does it direct, however I lost
where it was.

However I think this can be done as well.

I hope it helps?

Cor

"Derek Martin"
 
Hey Cor, thanks for your assistance, I also think I found an additional
solution - since I am pulling stuff out of SharePoint, I could in theory
query a view of a list instead of just the data results. Am trying that
now!

Derek
 

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

Back
Top