1

查询中的 datesList 只是日期时间值的列表。

使用 linq 查询/groupby,我将属于一年中某一周的所有这些日子分组到一个分组中。

Func<DateTime, int> weekProjector = d =>
CultureInfo.CurrentCulture.Calendar.GetWeekOfYear( d, CalendarWeekRule.FirstDay, DayOfWeek.Monday);

var weeks = (from date in datesList group date by weekProjector(date.Date)).ToList();

让我们假设周集合包含 8 个并且可以按 A 周和 B 周轮换。这意味着如果用户从 A 周开始,则按值 2 轮换会提供此结果:

AA、BB、AA、BB(8周,每周轮换2次)

AAAA、BBBB(8 周,每周轮换 4 次)

考虑到可以是从 1 到 8 的任意数字的轮换值,我如何将周集合和组/项目或任何日期时间值查询到单独的 weekListA/weekListB 中。

更新:

最终状态是 2 个列表 A 和 B 列表,每个列表都包含来自周集合的日期时间值。

更新 2:在这个样本中,每周轮换的因素为 4:这意味着我有 4 周的 A 型,4 周的 B 型等等

在此处输入图像描述

4

2 回答 2

4

我希望我正确地理解了你。

给定一堆日期,按一年中的星期分组:

// 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您的“轮换”(24)在哪里,并且是2您想要的组数(组AB=> 2组)。

您可能想添加到 aSelect之后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);
于 2013-02-18T13:17:11.390 回答
1

这可能是您正在寻找的,GroupBy Index % 2

var abRotations = datesList
    .GroupBy(d => CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(d, CalendarWeekRule.FirstDay, DayOfWeek.Monday))
    .Select((wg, i) => new { WeekGroup = wg, Index = i })
    .GroupBy(x => x.Index % 2);

List<DateTime> A_Rotation = abRotations.First().SelectMany(x => x.WeekGroup).ToList();
List<DateTime> B_Rotation = abRotations.Last().SelectMany(x => x.WeekGroup).ToList();

演示

于 2013-02-18T13:16:48.817 回答