how to sort a generic list of a structure

  • Thread starter Thread starter Guest
  • Start date Start date
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.
 
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
 
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);
 
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
 
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.
 
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);
 
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);
 
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.
 
ok so this section I think runs when the class is brought into focus. The
sort seems to be working now, thanks.
 
Back
Top