我有一个场景,我有一个时间表列表以及一个字符串字段,指示时间跨度是否应该在我所拥有的20个时间跨度的前16位。 例如:
BYVAL
我需要的是所有列表项目都有“自动”作为类型保留在前16位,无论排序后的时间如何。有时间(或其他值)的人可以低于第16项。
我想到的是用防止自动降到16以下的某种方法按时间对列表进行排序。然后我可以将17-20设置为替代。我根本不知道如何使用linq,我认为这将是最好的方式。
答案 0 :(得分:1)
要控制类的排序方式,您可以使类实现IComparable或创建一个实现IComparer的单独类。
不同之处在于实现IComparable<T>
指定了一个默认的排序顺序,如果有一些内在的,通常适用的明显排序顺序,这是有意义的。但在其他情况下,您可能有多种方法要对类进行排序。一个例子是.NET框架提供的各种StringComparer
类。它们都是IComparer<string>
的实现。
我没有上课,所以我编写了这个:
public class TimeSpanWithType
{
public TimeSpan Time { get; set; }
public string Type { get; set; }
}
这是一个比较器类,用类型&#34; auto&#34;对类进行排序。第一
public class AutoFirstComparer : IComparer<TimeSpanWithType>
{
public int Compare(TimeSpanWithType x, TimeSpanWithType y)
{
if (x.Type!=y.Type)
{
if (x.Type == "auto") return -1;
if (y.Type == "auto") return 1;
}
return x.Time.CompareTo(y.Time);
}
}
为方便起见,这里是一个静态类,因此您不必继续创建比较器的新实例。
public static class TimeSpanWithTypeComparison
{
public static IComparer<TimeSpanWithType> AutoFirst = new AutoFirstComparer();
}
这是一个单元测试,证明在排序时它会自动输出&#34;第一
[TestClass]
public class TimeSpanWithTypeComparisonTests
{
[TestMethod]
public void SortsAsExpected()
{
var time1 = new TimeSpanWithType() { Type = "xyz", Time = TimeSpan.FromHours(1) };
var time2 = new TimeSpanWithType() { Type = "auto", Time = TimeSpan.FromHours(3) };
var time3 = new TimeSpanWithType() { Type = "auto", Time = TimeSpan.FromHours(2) };
var sorted = new TimeSpanWithType[] { time1, time2, time3 }
.OrderBy(t => t, TimeSpanWithTypeComparison.AutoFirst).ToArray();
Assert.AreEqual(sorted[0], time3);
Assert.AreEqual(sorted[1], time2);
Assert.AreEqual(sorted[2], time1);
}
}
答案 1 :(得分:0)
这听起来像另一种说明问题的方式是:&#34;所有带有&#39; auto&#39;加上4个最快的没有&#39; auto&#39;&#34;。
var a = list.Where(x => x.Type == "auto").OrderBy(x => x.Time);
var b = list.Where(x => x.Type != "auto").OrderBy(x => x.Time).Take(4);
var result = a.Concat(b);