查询中的datesList只是datetime值的列表。

使用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进行轮播会产生以下结果:

A A,B B,A A,B B(8周,每周轮换2次)

A A A A,B B B B(8周,每周轮换4次)

如何考虑周转值(可以是1到8中的任何数字),如何将周集合和组/项目或其他日期时间值查询到单独的weekListA / weekListB中。

更新:

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

更新2:在此示例中,每周轮换的系数为4:这意味着我有4周的A型,4周的B型,依此类推

最佳答案

我希望我能正确理解你。

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

// 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个组)。

您可能想在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);

关于c# - 使用LINQ将日期/周的列表分为a和b周,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14936757/

10-12 07:39
查看更多