1

オブジェクトのリストがあります。各オブジェクトには、時刻を表すTimeSpanプロパティがあります。入力値に最も近い時間を取得する必要があります。

このように見えるはずです。

List<MyClass> list = new List<MyClass>
{
   new MyClass() {Name="midnight", time= new TimeSpan(0,0,0)},
   new MyClass() {Name="noon", time= new TimeSpan(12,0,0)},
};

var testOne = GetClosest(new TimeSpan(2, 0, 0),list); // returns midnight
var testTwo = GetClosest(new TimeSpan(8, 0, 0),list); // returns noon
var testThree = GetClosest(new TimeSpan(13, 0, 0),list); // returns noon
var testFour = GetClosest(new TimeSpan(22, 0, 0),list); // returns midnight (that's the tricky one)

これを行うためのエレガントな方法はありますか?

編集:もちろん、リストは渡されるべきです、ごめんなさい。

4

2 に答える 2

6

あなたも実際にリストを渡すと思いますか?効率はそれほど高くありませんが、基本的には、既存の時間と「次の同じ時間」の両方を試して、各ペア(元の時間と「目標」時間から)を0〜12時間の範囲にマッピングする必要があります。日"。例えば:

public static TimeSpan GetClosest(TimeSpan time, IEnumerable<TimeSpan> targets)
{
    return targets.OrderBy(x => BestFit(x, time))).First();
}

private static long BestFit(TimeSpan x, TimeSpan y)
{
    return Math.Min(Math.Abs((x - y).TotalTicks,
                    Math.Abs((x + TimeSpan.FromDays(1) - y).TotalTicks));
}

または、MoreLINQを使用して完全な並べ替えを回避しますが、単純な(さらに単純な)コードを維持します。

public static TimeSpan GetClosest(TimeSpan time, IEnumerable<TimeSpan> targets)
{
    return targets.MinBy(x => BestFit(x, time));
}

// BestFit as before
于 2013-03-10T20:27:40.223 に答える
0

速度を上げるために、中間リスト(直接または間接)を作成することもできます。

public static string GetFirstEqualOrHigher(TimeSpan time, IEnumerable<MyClass> targets)
{
    return list.First(x => time >= x.time).Name;
}

IList<MyClass> list = new List<MyClass>
{
    new MyClass() { Name="midnight", time = new TimeSpan(18, 0, 0) }
    new MyClass() { Name="noon", time = new TimeSpan(6, 0, 0) },
    new MyClass() { Name="midnight", time = new TimeSpan(0, 0, 0) },
};

var testOne = GetFirstEqualOrHigher(new TimeSpan(2, 0, 0), list); // returns midnight
var testTwo = GetFirstEqualOrHigher(new TimeSpan(8, 0, 0), list); // returns noon
var testThree = GetFirstEqualOrHigher(new TimeSpan(13, 0, 0), list); // returns noon
var testFour = GetFirstEqualOrHigher(new TimeSpan(22, 0, 0), list); // returns midnight (that's the tricky one
于 2013-03-10T20:47:54.293 に答える