得到最近的时间

MAK*_*MAK 1 .net c#

我有一个obect列表,每个对象有一个TimeSpan属性reprsenting时间.我需要得到一个时间最接近输入值的对象.

应该看起来像这样..

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)
Run Code Online (Sandbox Code Playgroud)

这有什么优雅的方式吗?

编辑:当然,列表应该通过,抱歉.

Jon*_*eet 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));
}
Run Code Online (Sandbox Code Playgroud)

或者使用MoreLINQ来避免完整排序,但保持简单(甚至更简单)的代码:

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

// BestFit as before
Run Code Online (Sandbox Code Playgroud)