私はあなたを正しく理解したことを願っています。
年の週ごとにグループ化された一連の日付が与えられます。
// some testdata
var datesList = Enumerable.Range(0, 8).Select (e => DateTime.Now.AddDays(7 * e)).ToList();
Func<DateTime, int> weekProjector = d =>
CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(d, CalendarWeekRule.FirstDay, DayOfWeek.Monday);
var weeks = datesList.GroupBy(weekProjector).ToList();
このクエリで必要な結果が得られるはずです。
var result = weeks.OrderBy(w => w.Key)
.Select((g, i) => new {WeekType = (i / rotation) % 2, Week = g})
.GroupBy(w => w.WeekType)
.ToList();
はrotation
「ローテーション」(2
または4
) で、2
は必要なグループの数です (グループA
とB
=> 2 グループ)。
Select
の後にを追加して、GroupBy
必要なデータのみを選択することもできます。たとえば、次のようになります。
var weekA = result.Where(r => r.Key==0).Select(g => g).SelectMany(g => g).SelectMany(a => a.Week).ToList();
var weekB = result.Where(r => r.Key==1).Select(g => g).SelectMany(g => g).SelectMany(a => a.Week).ToList();
より読みやすい/一般的なソリューション:
void Rotate<TResult, TGroup>(IEnumerable<TResult> datesList, Func<TResult, TGroup> grouper, int rotation, out List<TResult> listA, out List<TResult> listB)
{
listA = new List<TResult>();
listB = new List<TResult>();
var weeks = datesList.GroupBy(grouper).ToList();
var c_rotation = 0;
var c_list = listA;
using (var en = weeks.GetEnumerator())
while(en.MoveNext())
{
c_list.AddRange((IGrouping<TGroup, TResult>)en.Current);
c_rotation++;
if (c_rotation == rotation)
{
c_rotation = 0;
c_list = c_list == listA ? listB : listA;
}
}
}
次のように使用します。
List<DateTime> listA;
List<DateTime> listB;
Func<DateTime, int> weekProjector = d =>
CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(d, CalendarWeekRule.FirstDay, DayOfWeek.Monday);
Rotate(datesList, weekProjector, 2, out listA, out listB);