In C# trying to figure out the best data structure to group the array of month-end dates into pairs
For instance, my array looks like [2021-09-30,2021-10-31,2021-11-30,2021-12-31] and the output I am expecting is something like below so that I can loop 4 times
[2021-09-30,2021-10-31],[2021-10-31,2021-11-30],[2021-11-30,2021-12-31]
CodePudding user response:
This can be done using the LINQ Aggregate method but it's easier to use the MoreLINQ Pairwise operator:
var dates=new []{
new DateTime(2021,9,30),
...
};
var pairs=dates.Pairwise((a,b)=new {Start=a,End=b});
foreach(var pair in pairs)
{
var start=pair.Start;
...
}
You can use tuples instead of anonymous types to reduce allocations:
var pairs=dates.Pairwise((a,b)=(Start:a,End:b));
foreach(var pair in pairs)
{
var start=pair.Start;
...
}
Pairwise is a small function. You could add it directly to your code instead of installing the MoreLINQ package:
public static IEnumerable<TResult> Pairwise<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TSource, TResult> resultSelector)
{
if (source == null) throw new ArgumentNullException(nameof(source));
if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector));
return _(); IEnumerable<TResult> _()
{
using var e = source.GetEnumerator();
if (!e.MoveNext())
yield break;
var previous = e.Current;
while (e.MoveNext())
{
yield return resultSelector(previous, e.Current);
previous = e.Current;
}
}
}
Using Zip
Another option is to use Enumerable.Zip to combine the array with itself after skipping one element:
var pairs=dates.Zip(dates.Skip(1),(a,b)=>(Start:a,Start:b));
foreach(var pair in pairs)
{
var start=pair.Start;
...
}
CodePudding user response:
public Dictionary<DateTime, DateTime> GetDatePairs(DateTime[] dateArray)
{
if (dateArray.Length % 2 != 1)
{
throw new ArgumentException($"{nameof(dateArray)} contains an odd number of entries");
}
Dictionary<DateTime, DateTime> datepairs = new();
for (int i = 0; i < dateArray.Length; i )
{
datepairs.Add(dateArray[i], dateArray[i 1]);
i ;
}
return datepairs;
}
