Im tring to make sub-list based on main list with 9 records according to datetime ascending order & then pcName(string).
my sorted sublist need to be like below
ObjectList 1 :
2615,2019-11-22 16:03:22.150,Test1
2615,2019-11-22 16:03:22.200,Test1
2615,2019-11-22 16:03:22.250,Test1
2615,2019-11-22 16:03:22.300,Test1
ObjectList 2 :
2615,2019-11-22 16:03:22.350,Test2
2615,2019-11-22 16:03:22.400,Test2
ObjectList 3 :
2615,2019-11-22 16:03:22.450,Test1
2615,2019-11-22 16:03:22.500,Test1
ObjectList 4 :
2615,2019-11-22 16:03:22.550,Test3
This object list need to take according to sequence ObjectList[0] ,ObjectList[1] ,ObjectList[2] and ObjectList[3]
I mentioned below my sample code
But this only provides me 3 sublist sets(Item1) filter based with Test1, Test2 & Test3 and 9 sublists but i want as above 4 sub lists. where i want to change code ?? Please help me
private void button_Click(object sender, EventArgs e)
{
List<Identity> listOfIdentity = new List<Identity>()
{
new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.550"),PcName="Test3"},
new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.300"), PcName="Test1"},
new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.350"), PcName="Test2"},
new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.400"), PcName="Test2"},
new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.200"), PcName="Test1"},
new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.500"), PcName="Test1"},
new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.250"), PcName="Test1"},
new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.450"), PcName="Test1"},
new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.150"), PcName="Test1"}
};
List<Identity> sortedIdentity = listOfIdentity.OrderBy(x => x.QCTime).ThenBy(x => x.PcName).ToList(); // here i order by time and then pc name
var items1 = listOfIdentity.OrderBy(x => x.QCTime).ThenBy(x => x.PcName).GroupBy(x => x.PcName).Select(grp => grp.ToList()).ToList(); //sub list create based with **Test1, Test2 & Test3** (3 sub lists)
var items2 = listOfIdentity.OrderBy(x => x.QCTime).ThenBy(x => x.PcName).GroupBy(x => new { x.QCTime, x.PcName }).Select(grp => grp.ToList()).ToList(); //sub list create based with each time and pc name (9 sublists)
}
class Identity
{
public int id { get; set; }
public DateTime QCTime { get; set; }
public string PcName { get; set; }
}
Here is my solution using Linq.Aggregate
:
private void button_Click(object sender, EventArgs e)
{
List<Identity> listOfIdentity = new List<Identity>()
{
new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.550"), PcName="Test3"},
new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.300"), PcName="Test1"},
new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.350"), PcName="Test2"},
new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.400"), PcName="Test2"},
new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.200"), PcName="Test1"},
new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.500"), PcName="Test1"},
new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.250"), PcName="Test1"},
new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.450"), PcName="Test1"},
new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.150"), PcName="Test1"}
};
List<Identity> sortedIdentity = listOfIdentity.OrderBy(x => x.QCTime).ThenBy(x => x.PcName).ToList(); // here i order by time and then pc name
var result = sortedIdentity.Skip(1).Aggregate(new List<List<Identity>> { new List<Identity> { sortedIdentity[0] } }, (lists, curr) =>
{
if (curr.PcName == lists.Last()[0].PcName)
lists.Last().Add(curr);
else
lists.Add(new List<Identity> { curr });
return lists;
});
}
It iterates over each element and checks, if it's PcName is the same as previous. If it is, it goes on the same list, else new list is created with this element.
EDIT: More elegant solution suggested by Matt.G
List<Identity> sortedIdentity = listOfIdentity.OrderBy(x => x.QCTime).ThenBy(x => x.PcName).ToList();
var result = sortedIdentity.Aggregate(new List<List<Identity>>(), (lists, curr) =>
{
if (curr.PcName == lists.LastOrDefault()?.FirstOrDefault()?.PcName)
lists.Last().Add(curr);
else
lists.Add(new List<Identity> { curr });
return lists;
});