Reputation: 13
I need to group by a list by owner, town and "timeout". I will explain "timeout":
public class Ticket
{
public int pk { get; set; }
public string owner { get; set; }
public string reffering { get; set; }
public DateTime? created_time { get; set; }
}
And I got a List. I want to create a List> where each sublist contains a list of tickets where created_time is less than 10 seconds.
Here is a sample list of tickets :
pk owner reffering created_time
#1 John Sam 15/11/2017 11:33:20
#2 John Sam 15/11/2017 11:33:21
#3 Pat Jerry 15/11/2017 11:33:27
#4 John Sam 15/11/2017 11:33:28
#6 Pat Jerry 15/11/2017 11:33:35
#5 John Sam 15/11/2017 11:34:00
And I need to get a list of list with
pk owner reffering created_time
---#1 Sub List ---
#1 John Sam 15/11/2017 11:33:20
#2 John Sam 15/11/2017 11:33:21
#4 John Sam 15/11/2017 11:33:28
---#2 Sub List ---
#5 John Sam 15/11/2017 11:34:00
---#3 Sub List ---
#3 Pat Jerry 15/11/2017 11:33:27
#6 Pat Jerry 15/11/2017 11:33:35
Here my starting code but I can find out how to do this..
List<List<Ticket>> result = tickets.OrderBy(p => p.created_time).GroupBy(p => new { p.owner, p.reffering }).Select(g => g.ToList()).ToList();
Hope some can help especially with the elapsed time.. it makes me crazy!
Upvotes: 1
Views: 108
Reputation: 997
I'm not quite sure you can do all of this with LINQ, here is my implementation as your references
var ticketGroups = tickets.OrderBy(x => x.created_time)
.GroupBy(x => new { x.owner, x.reffering });
var tensecondTimespam = new TimeSpan(0, 0, 10);
var results = new List<List<Ticket>>();
var ticketTemps = new List<Ticket>();
foreach (var ticketGroup in ticketGroups)
{
foreach (var ticket in ticketGroup)
{
var currentTicket = ticketTemps.LastOrDefault();
var isWithinTimeRange = currentTicket == null
|| ticket.created_time.Value - currentTicket.created_time.Value <= tensecondTimespam;
if (!isWithinTimeRange)
{
results.Add(ticketTemps);
ticketTemps = new List<Ticket>();
}
ticketTemps.Add(ticket);
}
if (ticketTemps.Any())
{
results.Add(ticketTemps);
ticketTemps = new List<Ticket>();
}
}
The result variable will hold your expected output
Upvotes: 0
Reputation: 3746
Here is something that could help. It is grouping the entries by fixed buckets of 10 seconds.
void Main()
{
var ticketsList = new List<Ticket>();
ticketsList.Add(new Ticket { pk = 1, owner="John", reffering="Sam" , created_time = new DateTime(2017, 11, 15, 11, 33, 20) });
ticketsList.Add(new Ticket { pk = 2, owner="John", reffering="Sam" , created_time = new DateTime(2017, 11, 15, 11, 33, 21) });
ticketsList.Add(new Ticket { pk = 3, owner="Pat" , reffering="Jerry", created_time = new DateTime(2017, 11, 15, 11, 33, 27) });
ticketsList.Add(new Ticket { pk = 4, owner="John", reffering="Sam" , created_time = new DateTime(2017, 11, 15, 11, 33, 28) });
ticketsList.Add(new Ticket { pk = 6, owner="Pat" , reffering="Jerry", created_time = new DateTime(2017, 11, 15, 11, 33, 35) });
ticketsList.Add(new Ticket { pk = 5, owner="John", reffering="Sam" , created_time = new DateTime(2017, 11, 15, 11, 34, 00) });
var now = DateTime.Now;
var orderedList = ticketsList.OrderBy(p => p.created_time).GroupBy(p => new { p.owner, p.reffering }).Select(g => g.ToList());
// Here is the 10 seconds grouping. I'm basically creating a new date
// starting at the beginning of a 10 seconds interval. I will then
// use this new date to perform the grouping.
var normalizedGroupKeysList = ticketsList.Select(t => new { ticket = t, groupKey = t.created_time.HasValue ? t.created_time.Value.AddSeconds(-t.created_time.Value.Second % 10) : now });
var result = normalizedGroupKeysList.GroupBy(t => t.groupKey, t => t.ticket);
}
public class Ticket
{
public int pk { get; set; }
public string owner { get; set; }
public string reffering { get; set; }
public DateTime? created_time { get; set; }
}
The output is:
Key= 11/15/2017 11:33:20 AM
pk owner reffering created_time
1 John Sam 11/15/2017 11:33:20 AM
2 John Sam 11/15/2017 11:33:21 AM
3 Pat Jerry 11/15/2017 11:33:27 AM
4 John Sam 11/15/2017 11:33:28 AM
Key= 11/15/2017 11:33:30 AM
pk owner reffering created_time
6 Pat Jerry 11/15/2017 11:33:35 AM
Key= 11/15/2017 11:34:00 AM
pk owner reffering created_time
5 John Sam 11/15/2017 11:34:00 AM
If you want to dynamically group your tickets dynamically by group of 10 seconds in dynamic buckets, you should need some clustering algorithm to find the best partition of your data.
Upvotes: 1