how to sort a generic list of a structure

G

Guest

Hi I have a generic list that is populated with a structure. I would like to
be able to sort on values in the structure. I have
public struct mergoutstruct
{
public Int32 projectnumber;
public DateTime day;
public TimeSpan time;
public Double timeout;
}

List<mergeoutstruct> mergelist;
mergestruct newstruct;
newstruct = new mergeoutstruct();
merglist = new List<mergeoutstruct>();

newstruct.time = 1:0;
newstruct.projectnumber = 11;
newstruct.day= Convert.ToDateTime (9/5/2007);
newstruct.timeout=1.0;
merglist.Add(newstruct);

newstruct.time = 1:0;
newstruct.projectnumber = 10;
newstruct.day= Convert.ToDateTime (9/5/2007);
newstruct.timeout=1.0;
merglist.Add(newstruct);

newstruct.time = 2:0;
newstruct.projectnumber = 11;
newstruct.day= Convert.ToDateTime (9/6/2007);
newstruct.timeout=1.0;
merglist.Add(newstruct);

So I would like to sort the mergelist where the structures or odered by day
and by project number. This would cause the structures in merglist with the
same project number and date to be grouped together,so for the example above
after the sort I would like to see,
merglist[0].projectnumber =10, merglist[1].projectnumber = 11 merglist[2].
projectnumber = 11.

I am not sure if there is a way to do this.
Thanks.
 
J

Jon Skeet [C# MVP]

So I would like to sort the mergelist where the structures or odered by day
and by project number. This would cause the structures in merglist with the
same project number and date to be grouped together,so for the example above
after the sort I would like to see,
merglist[0].projectnumber =10, merglist[1].projectnumber = 11 merglist[2].
projectnumber = 11.

I am not sure if there is a way to do this.

I'd suggest using the "Sort" method of List<T>, possibly using an
anonymous method to specify the comparison.

I'd also recommend:

1) Using a class rather than a struct, given that it's mutable
2) Using properties rather than public fields
3) Following .NET naming conventions
4) Using a single DateTime to represent the date and time (as that's
what DateTime is)
5) Providing a constructor which lets you set all the values in one go
 
G

Guest

Paul said:
Hi I have a generic list that is populated with a structure. I would like to
be able to sort on values in the structure. I have
public struct mergoutstruct
{
public Int32 projectnumber;
public DateTime day;
public TimeSpan time;
public Double timeout;
}

List<mergeoutstruct> mergelist;
mergestruct newstruct;
newstruct = new mergeoutstruct();
merglist = new List<mergeoutstruct>();

newstruct.time = 1:0;
newstruct.projectnumber = 11;
newstruct.day= Convert.ToDateTime (9/5/2007);
newstruct.timeout=1.0;
merglist.Add(newstruct);

newstruct.time = 1:0;
newstruct.projectnumber = 10;
newstruct.day= Convert.ToDateTime (9/5/2007);
newstruct.timeout=1.0;
merglist.Add(newstruct);

newstruct.time = 2:0;
newstruct.projectnumber = 11;
newstruct.day= Convert.ToDateTime (9/6/2007);
newstruct.timeout=1.0;
merglist.Add(newstruct);

I don't like mutable structs...

public struct MergeOut {

private int _projectNumber;
private DateTime _day;
private TimeSpan _time;
private double _timeOut;

public MergeOut(int projectNumber, DateTime day, TimeSpan, time,
double timeOut) {
_projectNumber = projectNumber;
_day = day;
_time = time;
_timeOut = timeOut;
}

public int ProjectNumber { get { return _projectNumber; } }
public DateTime Day { get { return _day; } }
public TimeSpan Time { get { return _time; } }
public double TimeOut { get { return _timeOut; } }

}

List<MergeOut> mergeList = new List<MergeOut>();
mergeList.Add(new MergeOut(11, new DateTime(2007, 9, 5), 1:0, 1.0));
mergeList.Add(new MergeOut(10, new DateTime(2007, 9, 5), 1:0, 1.0));
mergeList.Add(new MergeOut(11, new DateTime(2007, 9, 5), 2:0, 1.0));
So I would like to sort the mergelist where the structures or odered by day
and by project number. This would cause the structures in merglist with the
same project number and date to be grouped together,so for the example above
after the sort I would like to see,
merglist[0].projectnumber =10, merglist[1].projectnumber = 11 merglist[2].
projectnumber = 11.

I am not sure if there is a way to do this.
Thanks.

Of course there is.

Add a comparer to the class:

public class Comparer : IComparer<MergeOut> {

public int Compare(MergeOut a, MergeOut b) {
int result = DateTime.Compare(a._day, b._Day);
if (result == 0) {
result = a._projectNumber.CompareTo(b._projectNumber);
}
return result;
}

}

Then you can use that to sort the list:

mergeList.Sort(MergeOut.Comparer);
 
G

Guest

Hi, thanks for the response. I tried using the sort method but could not
feed it the correct arguments. I am kind of new to some of the more advanced
features of C#. I was wondering if you have time could provide a brief
example on some of your suggestions. I think I can create the class ok,
based on the structure I already have.
--
Paul G
Software engineer.


Jon Skeet said:
So I would like to sort the mergelist where the structures or odered by day
and by project number. This would cause the structures in merglist with the
same project number and date to be grouped together,so for the example above
after the sort I would like to see,
merglist[0].projectnumber =10, merglist[1].projectnumber = 11 merglist[2].
projectnumber = 11.

I am not sure if there is a way to do this.

I'd suggest using the "Sort" method of List<T>, possibly using an
anonymous method to specify the comparison.

I'd also recommend:

1) Using a class rather than a struct, given that it's mutable
2) Using properties rather than public fields
3) Following .NET naming conventions
4) Using a single DateTime to represent the date and time (as that's
what DateTime is)
5) Providing a constructor which lets you set all the values in one go
 
J

Jon Skeet [C# MVP]

Paul said:
Hi, thanks for the response. I tried using the sort method but could not
feed it the correct arguments. I am kind of new to some of the more advanced
features of C#. I was wondering if you have time could provide a brief
example on some of your suggestions. I think I can create the class ok,
based on the structure I already have.

Unfortunately I'm too tired right now (it's half past midnight here)
but if you don't have some full examples tomorrow, I'll post again
then.
 
G

Guest

ok thanks will give this a try!
--
Paul G
Software engineer.


Göran Andersson said:
Paul said:
Hi I have a generic list that is populated with a structure. I would like to
be able to sort on values in the structure. I have
public struct mergoutstruct
{
public Int32 projectnumber;
public DateTime day;
public TimeSpan time;
public Double timeout;
}

List<mergeoutstruct> mergelist;
mergestruct newstruct;
newstruct = new mergeoutstruct();
merglist = new List<mergeoutstruct>();

newstruct.time = 1:0;
newstruct.projectnumber = 11;
newstruct.day= Convert.ToDateTime (9/5/2007);
newstruct.timeout=1.0;
merglist.Add(newstruct);

newstruct.time = 1:0;
newstruct.projectnumber = 10;
newstruct.day= Convert.ToDateTime (9/5/2007);
newstruct.timeout=1.0;
merglist.Add(newstruct);

newstruct.time = 2:0;
newstruct.projectnumber = 11;
newstruct.day= Convert.ToDateTime (9/6/2007);
newstruct.timeout=1.0;
merglist.Add(newstruct);

I don't like mutable structs...

public struct MergeOut {

private int _projectNumber;
private DateTime _day;
private TimeSpan _time;
private double _timeOut;

public MergeOut(int projectNumber, DateTime day, TimeSpan, time,
double timeOut) {
_projectNumber = projectNumber;
_day = day;
_time = time;
_timeOut = timeOut;
}

public int ProjectNumber { get { return _projectNumber; } }
public DateTime Day { get { return _day; } }
public TimeSpan Time { get { return _time; } }
public double TimeOut { get { return _timeOut; } }

}

List<MergeOut> mergeList = new List<MergeOut>();
mergeList.Add(new MergeOut(11, new DateTime(2007, 9, 5), 1:0, 1.0));
mergeList.Add(new MergeOut(10, new DateTime(2007, 9, 5), 1:0, 1.0));
mergeList.Add(new MergeOut(11, new DateTime(2007, 9, 5), 2:0, 1.0));
So I would like to sort the mergelist where the structures or odered by day
and by project number. This would cause the structures in merglist with the
same project number and date to be grouped together,so for the example above
after the sort I would like to see,
merglist[0].projectnumber =10, merglist[1].projectnumber = 11 merglist[2].
projectnumber = 11.

I am not sure if there is a way to do this.
Thanks.

Of course there is.

Add a comparer to the class:

public class Comparer : IComparer<MergeOut> {

public int Compare(MergeOut a, MergeOut b) {
int result = DateTime.Compare(a._day, b._Day);
if (result == 0) {
result = a._projectNumber.CompareTo(b._projectNumber);
}
return result;
}

}

Then you can use that to sort the list:

mergeList.Sort(MergeOut.Comparer);
 
G

Guest

Hi I was trying to set up your example but get the following error on MergeOut,
Class struct or interface must have a return type.

public MergeOut(int projectNumber, DateTime day, TimeSpan time,
double timeOut) {
_projectNumber = projectNumber;
_day = day;
_time = time;
_timeOut = timeOut;
}
--
Paul G
Software engineer.


Göran Andersson said:
Paul said:
Hi I have a generic list that is populated with a structure. I would like to
be able to sort on values in the structure. I have
public struct mergoutstruct
{
public Int32 projectnumber;
public DateTime day;
public TimeSpan time;
public Double timeout;
}

List<mergeoutstruct> mergelist;
mergestruct newstruct;
newstruct = new mergeoutstruct();
merglist = new List<mergeoutstruct>();

newstruct.time = 1:0;
newstruct.projectnumber = 11;
newstruct.day= Convert.ToDateTime (9/5/2007);
newstruct.timeout=1.0;
merglist.Add(newstruct);

newstruct.time = 1:0;
newstruct.projectnumber = 10;
newstruct.day= Convert.ToDateTime (9/5/2007);
newstruct.timeout=1.0;
merglist.Add(newstruct);

newstruct.time = 2:0;
newstruct.projectnumber = 11;
newstruct.day= Convert.ToDateTime (9/6/2007);
newstruct.timeout=1.0;
merglist.Add(newstruct);

I don't like mutable structs...

public struct MergeOut {

private int _projectNumber;
private DateTime _day;
private TimeSpan _time;
private double _timeOut;

public MergeOut(int projectNumber, DateTime day, TimeSpan, time,
double timeOut) {
_projectNumber = projectNumber;
_day = day;
_time = time;
_timeOut = timeOut;
}

public int ProjectNumber { get { return _projectNumber; } }
public DateTime Day { get { return _day; } }
public TimeSpan Time { get { return _time; } }
public double TimeOut { get { return _timeOut; } }

}

List<MergeOut> mergeList = new List<MergeOut>();
mergeList.Add(new MergeOut(11, new DateTime(2007, 9, 5), 1:0, 1.0));
mergeList.Add(new MergeOut(10, new DateTime(2007, 9, 5), 1:0, 1.0));
mergeList.Add(new MergeOut(11, new DateTime(2007, 9, 5), 2:0, 1.0));
So I would like to sort the mergelist where the structures or odered by day
and by project number. This would cause the structures in merglist with the
same project number and date to be grouped together,so for the example above
after the sort I would like to see,
merglist[0].projectnumber =10, merglist[1].projectnumber = 11 merglist[2].
projectnumber = 11.

I am not sure if there is a way to do this.
Thanks.

Of course there is.

Add a comparer to the class:

public class Comparer : IComparer<MergeOut> {

public int Compare(MergeOut a, MergeOut b) {
int result = DateTime.Compare(a._day, b._Day);
if (result == 0) {
result = a._projectNumber.CompareTo(b._projectNumber);
}
return result;
}

}

Then you can use that to sort the list:

mergeList.Sort(MergeOut.Comparer);
 
G

Guest

Paul said:
Hi I was trying to set up your example but get the following error on MergeOut,
Class struct or interface must have a return type.

public MergeOut(int projectNumber, DateTime day, TimeSpan time,
double timeOut) {
_projectNumber = projectNumber;
_day = day;
_time = time;
_timeOut = timeOut;
}

That is the constructor of the class. It should have the same name as
the class.
 
G

Guest

ok so this section I think runs when the class is brought into focus. The
sort seems to be working now, thanks.
 

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