Related
I have several classes of business logic:
public class Client {
public string Code { get; set; } = string.Empty;
public string Status { get; set; } = string.Empty;
public string Account { get; set; } = string.Empty;
public Total Total { get; set; } = new Total();
public List<Month> Months { get; set; } = new List<Month>();
}
public class Month {
public int Number { get; set; } = 0;
public string Name { get; set; } = string.Empty;
public DateTime Start { get; set; } = new DateTime();
public DateTime End { get; set; } = new DateTime();
public Total Summary { get; set; } = new Total();
}
public class Total {
public int Count { get; set; } = 0;
public decimal Sum { get; set; } = 0.0m;
}
which are instanced as follows:
List<Client> clients = new List<Client>() {
new Client {
Code = "7002.70020604",
Status = "Active",
Account = "7002.915940702810005800001093",
Total = new Total {
Count = 9,
Sum = 172536.45m
},
Months = new List<Month>() {
new Month {
Number = 0,
Name = "January",
Start = new DateTime(2021, 1, 1, 0, 0, 0),
End = new DateTime(2021, 1, 31, 23, 59, 59),
Summary = new Total {
Count = 6,
Sum = 17494.50m
}
},
new Month {
Number = 1,
Name = "February",
Start = new DateTime(2021, 2, 1, 0, 0, 0),
End = new DateTime(2021, 2, 28, 23, 59, 59),
Summary = new Total {
Count = 3,
Sum = 155041.95m
}
},
new Month {
Number = 2,
Name = "March",
Start = new DateTime(2021, 3, 1, 0, 0, 0),
End = new DateTime(2021, 3, 31, 23, 59, 59),
Summary = new Total {
Count = 0,
Sum = 0.0m
}
}
}
},
new Client {
Code = "7002.70020604",
Status = "Active",
Account = "7002.800540702810205800001093",
Total = new Total {
Count = 4,
Sum = 16711.21m
},
Months = new List<Month>() {
new Month {
Number = 0,
Name = "January",
Start = new DateTime(2021, 1, 1, 0, 0, 0),
End = new DateTime(2021, 1, 31, 23, 59, 59),
Summary = new Total {
Count = 0,
Sum = 0.0m
}
},
new Month {
Number = 1,
Name = "February",
Start = new DateTime(2021, 2, 1, 0, 0, 0),
End = new DateTime(2021, 2, 28, 23, 59, 59),
Summary = new Total {
Count = 0,
Sum = 0.0m
}
},
new Month {
Number = 2,
Name = "March",
Start = new DateTime(2021, 3, 1, 0, 0, 0),
End = new DateTime(2021, 3, 31, 23, 59, 59),
Summary = new Total {
Count = 4,
Sum = 16711.21m
}
}
}
}
};
I'm trying to arrange aggregate data of a view like this:
+---------------+--------+------------------+-------------------+------------------+-------------------+
| Code | Status | January | February | March | Total |
| | +-------+----------+-------+-----------+-------+----------+-------+-----------+
| | | Count | Sum | Count | Sum | Count | Sum | Count | Sum |
+---------------+--------+-------+----------+-------+-----------+-------+----------+-------+-----------+
| 7002.70020604 | Active | 6 | 17494.50 | 3 | 155041.95 | 4 | 16711.21 | 13 | 189247.66 |
+---------------+--------+-------+----------+-------+-----------+-------+----------+-------+-----------+
using projection like this:
clients
.GroupBy(x => x.Code)
.Select(y => new {
Code = y.First().Code,
Status = y.First().Status,
Account = y.First().Account,
Total = new {
Count = y.Sum(z => z.Total.Count),
Sum = y.Sum(z => z.Total.Sum)
},
Months = new {
/*
?
*/
}
});
But I can't project the data by month. Assuming the date range (months) can be more than just this example. Please help!
Full interactive code listing at dotnetfiddle
You can use SelectMany to get months out of y and then group by month similarly as you group by code:
//...
Months = y
.SelectMany(client => client.Months)
.GroupBy(month => month.Name, (_, months) => new {
Number = months.First().Number,
Name = months.First().Name,
Start = months.First().Start,
End = months.First().End,
Summary = new {
Count = months.Sum(z => z.Summary.Count),
Sum = months.Sum(z => z.Summary.Sum)
}
}).ToList()
//...
That being said I don't suggest to use y.First() or months.First() more than once in each function because it makes an enumeration each time it is used. The following should in general have better performance:
(_, months) => {
var month = months.First();
return new {
Number = month.Number,
Name = month.Name,
Start = month.Start,
End = month.End,
Summary = new {
Count = months.Sum(z => z.Summary.Count),
Sum = months.Sum(z => z.Summary.Sum)
}
}
}
which is also not ideal because we're still making 3 enumerations here (1 enumeration in .First() and 1 enumeration for every .Sum(...)).
Even better approach would be to use Aggregate function which will do only a single enumeration:
(_, months) => months
.Aggregate((res, nextVal) => new Month {
Number = nextVal.Number,
Name = nextVal.Name,
Start = nextVal.Start,
End = nextVal.End,
Summary = new Total {
Count = res.Summary.Count + nextVal.Summary.Count,
Sum = res.Summary.Sum + nextVal.Summary.Sum
}
})
This LINQ query should prepare data for visualization:
clients
.GroupBy(x => new {x.Code, x.Status})
.Select(g => new
{
Code = g.Key
MonthsSummary = g.SelectMany(x => x.Months)
.OrderBy(x => x.Start)
.GroupBy(x => new {x.Start, x.Name})
.Select(gm => new
{
gm.Key.Name,
Count = gm.Sum(x => x.Summary.Count),
Sum = gm.Sum(x => x.Summary.Sum),
})
.ToList()
});
I have a table called campaign which has a foreign key from a table called Snapshot.
I want to bring the records from the table Campaigns and for each foreign key (SnapShotID) to distinct them by the column CampaignName. So from the Foreign Key SnapShotID I want to use the DatasetID and then distinct by the CampaignName.
If I use distinctBy instead of distinct, if a campaignName belongs to different foreign Keys it will distinct them in all cases. However I want to distinct the value of the campaignName that corresponds to the same DatasetID
Concluding, as an outcome I am trying to: I have a campaignName called Upstream which belongs to foreign key (SnapshotID) 1,2 and 5. SnapshotID 1 and 2 corresponds to Planning and 5 corresponds to Production. So, I want to bring all records and filter the campaign name for each DataSetID. So Upstream should come twice. One that is connected to Production and one that is connected to Planning. However Upstream in Planning it will be distincted as it exists twice.
Snapshot Table
Campaign Table
As sample: I tried
var campaigns = db.Campaigns.Include(c => c.Snapshot)
.OrderBy(i => i.Snapshot.DatasetID)
.ThenBy(i => i.CampaignName.Distinct());
The above one throws me an exception => DbDistinctExpression requires a collection argument.
Parameter name: argument
var campaigns = db.Campaigns.Include(c => c.Snapshot)
.GroupBy(i => i.Snapshot.DatasetID)
.Select(i => i.CampaignName.Distinct());
The above does not compile
So, I tried many combinations but also did not work.
If it is possible i would like help so that the query to be written mainly in lambda and then the same query in LINQ
I simulated your database with classes to show correct syntax. You have to check that creation date is between start and end dates.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
namespace ConsoleApplication11
{
class Program
{
const string FILENAME = #"c:\temp\test.txt";
static void Main(string[] args)
{
DataBase db = new DataBase()
{
Snapshot = new List<Snapshot>() {
new Snapshot() { Id = 1, CreationDate = new DateTime(2019, 10, 1, 8,0,0), DatasetID = "Planning"},
new Snapshot() { Id = 2, CreationDate = new DateTime(2019, 10, 2, 8,0,0), DatasetID = "Planning"},
new Snapshot() { Id = 3, CreationDate = new DateTime(2019, 10, 15, 13,0,0), DatasetID = "Production"},
new Snapshot() { Id = 4, CreationDate = new DateTime(2019, 10, 16, 14,0,0), DatasetID = "Production"},
new Snapshot() { Id = 5, CreationDate = new DateTime(2019, 10, 16, 17,0,0), DatasetID = "Production"}
},
Campaign = new List<Campaign>() {
new Campaign() { Id = 1, CampaignName = "Upstream", StartDate = new DateTime(2019, 11, 1, 8,0,0), EndDate = new DateTime(2019, 11, 2, 17,0,0), SnapshotID = 1},
new Campaign() { Id = 2, CampaignName = "Downstream", StartDate = new DateTime(2019, 11, 3, 8,0,0), EndDate = new DateTime(2019, 11, 6, 15,0,0), SnapshotID = 2},
new Campaign() { Id = 3, CampaignName = "Upstream", StartDate = new DateTime(2019, 11, 1, 10,0,0), EndDate = new DateTime(2019, 11, 2, 18,0,0), SnapshotID = 2},
new Campaign() { Id = 4, CampaignName = "BufferPrep", StartDate = new DateTime(2019, 12, 1, 6,0,0), EndDate = new DateTime(2019, 12, 5, 15,0,0), SnapshotID = 3},
new Campaign() { Id = 5, CampaignName = "Product1", StartDate = new DateTime(2019, 12, 6, 8,0,0), EndDate = new DateTime(2019, 12, 7, 19,0,0), SnapshotID = 4},
new Campaign() { Id = 6, CampaignName = "Product2", StartDate = new DateTime(2019, 12, 8, 8,0,0), EndDate = new DateTime(2019, 12, 9, 20,0,0), SnapshotID = 5},
new Campaign() { Id = 7, CampaignName = "BufferPrep", StartDate = new DateTime(2019, 12, 1, 12,0,0), EndDate = new DateTime(2019, 12, 6, 10,0,0), SnapshotID = 5},
new Campaign() { Id = 9, CampaignName = "Upstream", StartDate = new DateTime(2019, 11, 5, 0,0,0), EndDate = new DateTime(2019, 11, 9, 0,0,0), SnapshotID = 5}
}
};
var groups = (from s in db.Snapshot
join c in db.Campaign on s.Id equals c.SnapshotID
select new { snapshot = s, campaign = c }
)
.GroupBy(x => x.snapshot.Id)
.ToList();
var results = groups.Select(x => new
{
snapshot = x.First().snapshot,
campaign = x.GroupBy(y => y.campaign.CampaignName).Select(y => y.First().campaign).ToList()
}).ToList();
}
}
public class DataBase
{
public List<Snapshot> Snapshot { get; set; }
public List<Campaign> Campaign { get; set; }
}
public class Snapshot
{
public int Id { get; set; }
public DateTime CreationDate { get; set; }
public string DatasetID { get; set; }
}
public class Campaign
{
public int Id { get; set; }
public string CampaignName { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public int SnapshotID { get; set; }
}
}
Initial Result without distinct
I configured the query: var campaigns = db.Campaigns.Include(c => c.Snapshot) .GroupBy(i => i.Snapshot.DatasetID).AsEnumerable() .SelectMany(i =>i.DistinctBy(z=>z.CampaignName)); which does the distinct that i want but this time does not display me the value of the DataSetID
New Result
This time, how can i display the DataSetID value ?
This is the View .cshtml
I have a collection where I am trying to sort the records first by Quarter and then inside the quarter by highest amounts. My code so far is:
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
List<Test> lstTest = new List<Test>();
lstTest.Add(new Test { dt = new DateTime(2017, 1, 2), amount = 2500 });
lstTest.Add(new Test { dt = new DateTime(2017, 1, 2), amount = 10000 });
lstTest.Add(new Test { dt = new DateTime(2017, 1, 5), amount = 4000 });
lstTest.Add(new Test { dt = new DateTime(2017, 1, 10), amount = 40000 });
lstTest.Add(new Test { dt = new DateTime(2017, 1, 15), amount = 2000 });
lstTest.Add(new Test { dt = new DateTime(2017, 1, 25), amount = 12000 });
lstTest.Add(new Test { dt = new DateTime(2017, 2, 5), amount = 38000 });
lstTest.Add(new Test { dt = new DateTime(2017, 2, 10), amount = 38000 });
lstTest.Add(new Test { dt = new DateTime(2017, 2, 15), amount = 4000 });
lstTest.Add(new Test { dt = new DateTime(2017, 2, 20), amount = 2000 });
lstTest.Add(new Test { dt = new DateTime(2017, 2, 20), amount = 20000 });
lstTest.Add(new Test { dt = new DateTime(2017, 3, 15), amount = 2000 });
lstTest.Add(new Test { dt = new DateTime(2017, 3, 20), amount = 2000 });
lstTest.Add(new Test { dt = new DateTime(2017, 3, 20), amount = 4000 });
lstTest.Add(new Test { dt = new DateTime(2017, 3, 31), amount = 1000 });
lstTest.Add(new Test { dt = new DateTime(2017, 4, 9), amount = 50000 });
lstTest.Add(new Test { dt = new DateTime(2017, 4, 11), amount = 2000 });
lstTest.Add(new Test { dt = new DateTime(2017, 4, 21), amount = 1000 });
lstTest.Add(new Test { dt = new DateTime(2017, 4, 21), amount = 10000 });
lstTest.Add(new Test { dt = new DateTime(2017, 4, 28), amount = 5000 });
lstTest.Add(new Test { dt = new DateTime(2017, 5, 5), amount = 45000 });
lstTest.Add(new Test { dt = new DateTime(2017, 5, 7), amount = 98000 });
lstTest.Add(new Test { dt = new DateTime(2017, 5, 9), amount = 7000 });
lstTest.Add(new Test { dt = new DateTime(2017, 5, 25), amount = 2000 });
lstTest.Add(new Test { dt = new DateTime(2017, 5, 31), amount = 1000 });
var result = lstTest.Select(x => new
{
Amount = x.amount,
Date = x.dt,
MonthDiff = GetMonthsDiff(DateTime.Now, x.dt),
Quater = GetQuarter(DateTime.Now, x.dt)
}).OrderBy(o=>o.Quater).ToList();
foreach (var res in result)
{
Console.WriteLine("Amount = {0} Date= {1} MonthDiff= {2} Quater= {3}", res.Amount, res.Date, res.MonthDiff, res.Quater);
}
Console.ReadKey();
}
public static string GetQuarter(DateTime start, DateTime end)// int month)
{
int month = GetMonthsDiff(start, end);
string quarter = month <= 3 ? "Q1" : (month >= 4 && month <= 6) ? "Q2" : (month >= 7 && month <= 9) ? "Q3" : "Q4";
return quarter;
}
public static int GetMonthsDiff(DateTime start, DateTime end)
{
if (start > end)
return GetMonthsDiff(end, start);
int months = 0;
do
{
start = start.AddMonths(1);
if (start > end)
return months;
months++;
}
while (true);
}
}
public class Test
{
public DateTime dt { get; set; }
public int amount { get; set; }
}
}
The output is
If I do OrderBy(o=>o.Quater).OrderByDescending(o=>o.Amount) the output changes to
That is it is first sorting by Quarter and then by Amount.
But I am looking for first sort by Quarter and within the Quarter sort by Amount descending.
The desired output is
What needs to be modified in the program so as achieve the target?
replace
OrderBy(o=>o.Quater).OrderByDescending(o=>o.Amount)
with
OrderBy(o=>o.Quater).ThenByDescending(o=>o.Amount)
ThenByDescending performs a subsequent ordering of the elements in a
sequence in descending order by using a specified comparer.
Here you are sorting the list two times, you are getting the output of the final sort only, if you want to perform the second sort over the sorted result of the first then you have to make use of ThenByDescending(if you want the second sort in descending order or else use ThenBy()) followed by OrderBy as like this:
var sortedItems = lstTest.OrderBy(o=>o.Quater).ThenByDescending(o=>o.Amount);
I have modified the code here in this example, you can check the output in the fiddle
You don't need to sort by a single property only. You can return the sort fields as an anonymous object tuple.
In C# 7 you can write :
OrderBy(o => (o.Quarter,o.Amount));
In previous versions :
OrderBy(o => Tuple.Create(o.Quarter,o.Amount));
If you want to use different sort orders you have to specify the fields one at a time, eg:
OrderBy(o=>o.Quarter).ThenByDescending(o=>o.Amount);
Or you can use query syntax to make the code cleaner:
var result = ( from x in lstTest
let o = new {
Amount = x.amount,
Date = x.dt,
MonthDiff = GetMonthsDiff(DateTime.Now, x.dt),
Quarter = GetQuarter(DateTime.Now, x.dt)
}
orderby o.Quarter, o.Amount descending
select o
).ToList()
I have a list of objects in which every object is containing a list itself. how do I get the the JellyFishID field or the Amount field for using an IF argument
(I'm currently using Foreach):`
public static List<Report> DataSorted = new List<Report> {
new Report() { IsGoldUser=true, Date=new DateTime(2016, 3, 12,11, 59, 33), IsBurningWater=true, Type=Type.Shore, ZoneID = 1 ,
ReportDetails =new List<ReportDetail> { new ReportDetail() { Amount = Amount.Few, Jellyfish = new Jellyfish { JellyfishID = 1, Venom = Venom.Strong } } } },
new Report() { IsGoldUser=true, Date=new DateTime(2016, 3, 12, 11, 59, 33), IsBurningWater=true, Type=Type.Shore, ZoneID = 1 ,
ReportDetails =new List<ReportDetail> { new ReportDetail() { Amount = Amount.Few, Jellyfish = new Jellyfish { JellyfishID = 1, Venom = Venom.Strong } } } },
new Report() { IsGoldUser=true, Date=new DateTime(2016, 3, 12, 11, 59, 33), IsBurningWater=true, Type=Type.Shore, ZoneID = 1 ,
ReportDetails =new List<ReportDetail> { new ReportDetail() { Amount = Amount.Few, Jellyfish = new Jellyfish { JellyfishID = 1, Venom = Venom.Strong } } } },
new Report() { IsGoldUser=true, Date=new DateTime(2016, 3, 12, 11, 59, 33), IsBurningWater=true, Type=Type.Shore, ZoneID = 1 ,
ReportDetails =new List<ReportDetail> { new ReportDetail() { Amount = Amount.Few, Jellyfish = new Jellyfish { JellyfishID = 1, Venom = Venom.Strong } } } },
foreach (var item in DataSorted)
{
if (item.ReportDetails....) //???I want here to Make an Argument about The Amount field or the JellyFishID field in the list above....
}
You don't describe exactly what you want to check, but with LINQ to Objects you have a lot of possiblities. At first, you need to reference the correct namespace with
using System.Linq;
at the top of your source code file.
Now, if you want to check if any items of your list contains a jellyfish with a given ID, you can use:
if (item.ReportDetails.Any(t => t.Jellyfish.JellyfishID == 1)) //...
Additionally you can have conditions inside a Where-function to filter your list and search only for jellyfish with a few amount:
if (item.ReportDetails.Where(t => t.Amount == Amount.Few).
Any(t => t.Jellyfish.JellyfishID == 1)) //...
There is a lot of information avaliable about LINQ, a lot of examples are in the MSDN (for example this intro page), but there are alternatives like this one: 101 Linq examples. It even has a tag on StackOverflow.
I'm facing an issue which I can't find a proper and elegant solution. I have a List of Videos, which is a class that contains informations about a video. Among those informations there is a startDate,endDate and an cameraId property.
My current database has the following values:
startDate endDate
I want to iterate through those values and when a video is within 5 minutes difference from the last one and has the same cameraId it should be counted as one. But I can't find a proper nor elegant way to accomplish this task.
The output for the videos list shown above should be
1st: 2013:03:01 18:25:26 -> 2013-03-01 18:34:29
2nd: 2013:03:01 18:40:26 -> 2013:03:01 18:59:29
This is the code I have so far:
private void ProcessVideos(List<Video> videos)
{
bool isSameVideo = false;
Video lastVideo = null;
//debugar e ver esquema do ultimo valor do database
DateTime startDate = DateTime.MinValue;
DateTime endDate = DateTime.MinValue;
for (int i = 1; i < videos.Count; i++)
{
TimeSpan timeSpan = new TimeSpan(videos[i].DataInicio.Ticks - videos[i - 1].DataFim.Ticks);
if (timeSpan.Minutes > 0 && timeSpan.Minutes < 5 && videos[i].IdCamera == videos[i - 1].IdCamera)
{
if (!isSameVideo)
{
isSameVideo = true;
startDate = videos[i - 1].DataInicio;
endDate = videos[i].DataFim;
}
else
{
endDate = videos[i].DataFim;
}
}
else
{
if (isSameVideo)
{
i++;
isSameVideo = false;
Debug.WriteLine("inicio: {0} fim: {1}", startDate, endDate);
startDate = DateTime.MinValue;
endDate = DateTime.MinValue;
}
Debug.WriteLine("inicio: {0} fim: {1}", videos[i - 1].DataInicio, videos[i - 1].DataFim);
}
}
if (startDate != DateTime.MinValue)
{
Debug.WriteLine("inicio: {0} fim: {1}", startDate, endDate);
}
}
The main question is: What is a good logic to iterate through those values and output a combinations of values according to the timespan specification?
I created a small example to show you:
My container object:
internal class Container
{
public int Id { get; set; }
public DateTime Start { get; set; }
public DateTime Stop { get; set; }
public override string ToString()
{
return "ID " + Id + ": " + Start + " -> " + Stop;
}
}
My method:
private static IEnumerable<Container> DoMerge(List<Container> elements, TimeSpan maxDiff)
{
var closedContainers = new List<Container>();
var lastContainers = new Dictionary<int, Container>();
foreach (Container container in elements.OrderBy(e => e.Start))
{
//First case, no previous container
if (!lastContainers.ContainsKey(container.Id))
{
lastContainers[container.Id] = container;
}
else if (container.Start - lastContainers[container.Id].Stop > maxDiff)
//We have a container, but not in our windows of 5 minutes
{
closedContainers.Add(lastContainers[container.Id]);
lastContainers[container.Id] = container;
}
else
{
//We have to merge our two containers
lastContainers[container.Id].Stop = container.Stop;
}
}
//We have now to put all "lastContainer" in our final list
foreach (KeyValuePair<int, Container> lastContainer in lastContainers)
{
closedContainers.Add(lastContainer.Value);
}
return closedContainers;
}
And we just have to give our max timespan and list of elements:
private static void Main(string[] args)
{
var elements = new List<Container>
{
new Container {Id = 1, Start = new DateTime(2013, 3, 1, 18, 25, 26), Stop = new DateTime(2013, 3, 1, 18, 27, 29)},
new Container {Id = 1, Start = new DateTime(2013, 3, 1, 18, 30, 26), Stop = new DateTime(2013, 3, 1, 18, 34, 29)},
new Container {Id = 1, Start = new DateTime(2013, 3, 1, 18, 40, 26), Stop = new DateTime(2013, 3, 1, 18, 52, 29)},
new Container {Id = 1, Start = new DateTime(2013, 3, 1, 18, 55, 26), Stop = new DateTime(2013, 3, 1, 18, 59, 29)},
};
foreach (Container container in DoMerge(elements, TimeSpan.FromMinutes(5)))
{
Console.WriteLine(container);
}
Console.ReadLine();
}
This give me your expected results we two objects lefts.
Result with the mentionned data:
Here's a solution. The crux of the method is shown in the ExtractVidTimes method. The rest is just for creating the sample data
[TestFixture]
public class TestyMcTest
{
public class Vid
{
public int CamId;
public DateTime Start;
public DateTime End;
}
[Test]
public void Test()
{
var list = new List<Vid>
{
//=====Combination1=======
new Vid
{
CamId = 1,
Start = new DateTime(2000, 1, 1, 0, 0, 0),
End = new DateTime(2000, 1, 1, 0, 3, 0)
},
new Vid
{
CamId = 1,
Start = new DateTime(2000, 1, 1, 0, 5, 0),
End = new DateTime(2000, 1, 1, 0, 7, 0)
},
//=====Combination2=======
new Vid
{
CamId = 1,
Start = new DateTime(2000, 1, 1, 0, 15, 0),
End = new DateTime(2000, 1, 1, 0, 18, 0)
},
//=====Combination3=======
new Vid
{
CamId = 2,
Start = new DateTime(2000, 1, 1, 0, 0, 0),
End = new DateTime(2000, 1, 1, 0, 3, 0)
},
//=====Combination4=======
new Vid
{
CamId = 2,
Start = new DateTime(2000, 1, 1, 0, 10, 0),
End = new DateTime(2000, 1, 1, 0, 13, 0)
}
};
//here is your list of vids grouped by the cam id
var result = ExtractVidTimes(list);
}
//THE METHOD
private static List<List<Vid>> ExtractVidTimes(List<Vid> list)
{
//Group by cam ID
var vidGroups = list.GroupBy(vid => vid.CamId).ToList();
//extract vids with aggregate times
var result = vidGroups.Select(vids =>
{
var vidTimes = new List<Vid>();
var finalVid = vids.OrderBy(vid=> vid.Start).Aggregate((a, b) =>
{
if (a.End.AddMinutes(5) > b.Start)
{
a.End = b.End;
return a;
}
vidTimes.Add(a);
return b;
});
vidTimes.Add(finalVid);
return vidTimes;
}).ToList();
//return result.SelectMany(x=>x); //if you want a List<vid> return ed instead of a nested list
return result;
}
}