1

クエリの datesList は、datetime 値の単なるリストです。

linq query/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 になります。つまり、タイプ A が 4 週間、タイプ B が 4 週間ということになります。

ここに画像の説明を入力

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「ローテーション」(2または4) で、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);
于 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 に答える