I have this view model that is a List containing StartDate
and EndDate
. I want to change this range list so if the difference in days between the next start and erevious end date is 1, merge the two ranges into each other.
For example, give this data:
2024/03/21-2024/03/22
2024/03/23-2024/03/25
2024/03/26-2024/03/28
2024/04/01-2024/04/02
I want change to see this result:
2024/03/21-2024/03/28
2024/04/01-2024/04/02
I have this code that runs, but too slowly:
var count = datas.Count();
for (int i = 0; i < count; i++)
{
TimeSpan def =(datas[i + 1].StartDate-datas[i].EndDate);
int diff = int.Parse(def.ToString());
if ((int)diff == 1)
datas[i].EndDate=datas[i + 1].EndDate;
}
How can I improve it?
It looks like you have a datas
list of an object with two DateTime properties, but we don't know the name of the type of this object. For this purpose, I will pretend the type name is Range
.
For simplicity, I will also assume the input always has at least one item. Finally, I will assume (based on the prior attempted question) that the Range objects in your collection are already sorted in order.
Given that information, we can process it with this method:
IEnumerable<Range> Consolidate(IEnumerable<Range> input)
{
Range buffer = input.First();
DateTime border = buffer.EndDate.AddDays(1);
foreach(var r in input.Skip(1))
{
if (r.StartDate <= border)
{
// it's part of the same range
buffer.EndDate = r.EndDate;
}
else
{
// it's a new range
yield return buffer;
buffer = r;
}
border = buffer.EndDate.AddDays(1);
}
yield return buffer;
}
which you would call like this:
var datas = Consolidate(datas).ToList();
Note, this code can also work if datas
is an array or other IEnumerable<Range>
by just changing the ToList()
call at the end. Additionally, avoiding ToList()
and friends can significantly improve memory use and execution time.
See it work here: