問題をいくつかの小さな部分に分割します。
注:すべての以下のメソッドは、この
public static class DayOfWeekExtensions
{
}
ファーストのようなクラスの中に置くことになっている、あなたはDayOfWeek
enum
でそれが最初に定義されている間Sunday
は、週の最後の日になりたいです。レッツもピボットを与えられた機能を追加
public static int OffsetTo(this DayOfWeek source, DayOfWeek target)
{
return source.GetIndex() - target.GetIndex();
}
と:2つのDayOfWeek
値の間に続いて、我々は(オフセット)までの距離を計算する関数が必要
public static int GetIndex(this DayOfWeek source)
{
return source == DayOfWeek.Sunday ? 6 : (int)source - 1;
}
:だから占め機能を作ってみよう2つのDayOfWeek
値(自分の前方の優先ルールを適用)2の最も近い値を選択します。
public static DayOfWeek Closest(this DayOfWeek pivot, DayOfWeek first, DayOfWeek second)
{
int comp = Math.Abs(first.OffsetTo(pivot)).CompareTo(Math.Abs(second.OffsetTo(pivot)));
return comp < 0 || (comp == 0 && first.GetIndex() > pivot.GetIndex()) ? first : second;
}
は、今、私たちはどのメソッドを実装する準備ができていますシーケンスから最も近い日を見つけます。 !
public static DayOfWeek? Closest(this IEnumerable<DayOfWeek> source, DayOfWeek target)
{
if (!source.Any()) return null;
return source.Aggregate((first, second) => target.Closest(first, second));
}
最後に、最も近い距離を計算する関数を追加してみましょう:
public static int ClosestDistance(this IEnumerable<DayOfWeek> source, DayOfWeek target)
{
return source.Closest(target)?.OffsetTo(target) ?? 0;
}
そして、我々は最終的には(使用して実装したものです:) LINQ Aggregate
方法ここでは、多くの方法で実施することができますされます。小さな単純な再利用可能なユーティリティクラスを作成しました。
あなたのケースでの使用は、次のようになります。
int dayOfWeekDistance = targetDayOfWeekList.ClosestDistance(passedInDate.DayOfWeek);
UPDATE:それはあなたの要件が異なっていることが判明しました。
同じ原則を適用するには、まず、前方優先ルールを適用して、週2日の間の前方および後方距離の最小値を計算する関数が必要です。それは基本的に何
public static int MinDistanceTo(this DayOfWeek from, DayOfWeek to)
{
int dist = to - from;
return dist >= 4 ? dist - 7 : dist <= -4 ? dist + 7 : dist;
}
-3..3
包含範囲内の値に可能-6..6
包括範囲から値を変換することです。
その後、我々は(それもMin
とカスタム比較演算で実現することができる)Select
+ Aggregate
を使用することによって、問題のメソッドを実装しますちょうど1より多くの機能を、必要があります。それは基本的に2つの絶対距離を比較し、再び前方の優先ルールを適用します。
public static int MinDistanceTo(this DayOfWeek from, IEnumerable<DayOfWeek> to)
{
if (!to.Any()) return 0;
return to.Select(x => from.MinDistanceTo(x)).Aggregate((dist1, dist2) =>
{
if (dist1 == dist2) return dist1;
int comp = Math.Abs(dist1).CompareTo(Math.Abs(dist2));
return comp < 0 || (comp == 0 && dist1 > 0) ? dist1 : dist2;
});
}
と使用方法は次のようになります。
int dayOfWeekDistance = passedInDate.DayOfWeek.MinDistanceTo(targetDayOfWeekList);
私はこれをテストしたが、このを見て時間を持っていなかった[質問](https://stackoverflow.com/questions/20056048/linq-lambda-式 - 最も近い週の曜日 - 現在の日付 - 現在) – aaronR
2つの日付の差異であるTimeSpanを計算しています。 DateTimeのデフォルトの時刻は深夜です。最初の質問はあなたが何時を比較しているのですか?真夜中か別の時間ですか? – jdweng
深夜になります。 – wibby35