C# 最接近的时间

C# 最接近的时间,c#,.net,C#,.net,我有一个对象列表,每个对象都有一个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 te

我有一个对象列表,每个对象都有一个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)
有什么优雅的方法吗


编辑:当然应该传递列表,对不起。

我想你也会传递列表?它的效率不如它可能的高,但基本上,您希望通过尝试现有时间和第二天的同一时间,将每一对从原始时间和目标时间映射到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));
}
或者使用以避免完全排序,但保持简单甚至更简单的代码:

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

// BestFit as before

我想你也会把名单传过来?它的效率不如它可能的高,但基本上,您希望通过尝试现有时间和第二天的同一时间,将每一对从原始时间和目标时间映射到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));
}
或者使用以避免完全排序,但保持简单甚至更简单的代码:

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

// BestFit as before

您还可以直接或间接创建一个中间列表,以提高速度:

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

您还可以直接或间接创建一个中间列表,以提高速度:

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

这与@EdmundYeung99非常相似-是的,但它的时间没有固定到某个特定日期-这使解决方案大不相同。这与@EdmundYeung99非常相似-是的,但它的时间没有固定到某个特定日期-这使解决方案大不相同。对不起,你的方法没有按照我的需要工作。在最后一种情况下,GetClosestNewTimeSpan22,0,0;它将返回中午时间-12,但我需要它返回最近的时间,即midnight@MAK:那么你到底希望它知道哪些选项是可用的呢?您正在调用方法中声明列表,但没有将其传递到任何地方。基本上,你最初提出的问题是不可能的。或者,如果你实际上是指晚上10点接近午夜,你应该更具体一点-我可以试着解决这个问题。或者,如果你实际上是指晚上10点接近午夜,这正是我的意思,再次抱歉。@MAK:对,所以你根本没有打电话给GetClosestnew TimeSpan22,0,0。明确这类事情是非常重要的——毕竟你是在请求别人帮助你。现在编辑它。谢谢你,乔恩,它按预期工作。你帮了我很多。对不起,你的方法没有按我需要的那样工作。在最后一种情况下,GetClosestNewTimeSpan22,0,0;它将返回中午时间-12,但我需要它返回最近的时间,即midnight@MAK:那么你到底希望它知道哪些选项是可用的呢?您正在调用方法中声明列表,但没有将其传递到任何地方。基本上,你最初提出的问题是不可能的。或者,如果你实际上是指晚上10点接近午夜,你应该更具体一点-我可以试着解决这个问题。或者,如果你实际上是指晚上10点接近午夜,这正是我的意思,再次抱歉。@MAK:对,所以你根本没有打电话给GetClosestnew TimeSpan22,0,0。明确这类事情是非常重要的——毕竟你是在请求别人帮助你。现在编辑它。谢谢你,乔恩,它按预期工作。你帮了我很大的忙。那只是找到第一个条目,它在最初的时间之后。。。例如,上午8点应该返回正午,这和最近的一个不一样。@Jon Skeet:不完全一样。我修改了时间,让它们正好在中间。只需查找中间位置之后的第一个,即可找到正确的名称。添加了一个工作示例,它显示了正确的名称。啊,我明白了。是的,尽管MyClass中的值在任何其他方面都是错误的…那只是在原始时间之后查找第一个条目。。。例如,上午8点应该返回正午,这和最近的一个不一样。@Jon Skeet:不完全一样。我修改了时间,让它们正好在中间。只需查找中间位置之后的第一个,即可找到正确的名称。添加了一个工作示例,它显示了正确的名称。啊,我明白了。是的,尽管MyClass中的值在其他方面是错误的。。。