2013-02-05 44 views
0

我有一个变量List< Tuple< DateTime, double>> myList
给定一个datetime,希望它通过使用Linq返回Tuple之前 datetime
例如,提供if "2013-Feb-08 21:34:00",想要 查看列表中的最后一个元组,其日期时间在此之前timestamp列表元组日期时间

我该怎么做Linq

编辑:
myList.Where(t => t.Item1 < timestamp).Last();
解决了我的问题。 在性能方面哪个更好
myList.TakeWhile(t => t.Item1 < timestamp).Last();

+0

使用[.OderByDescending](http://stackoverflow.com/questions/5344805/linq -orderby-descending-query) – spajce

+0

我想要的元素可能不是orderby列表中的第一个元素。 – Chris

+0

“last”,你的意思是列表中索引最高的项目,还是具有最高“DateTime”值的项目? – Guffa

回答

2

随着MoreLinq MaxBy(可从的NuGet):

myList.Where(t => t.Item1 < timestamp).MaxBy(t => t.Item1); 

或者(如果项目排序):

myList.TakeWhile(t => t.Item1 < timestamp).Last(); 

UPDATE(二进制搜索)写的比较器:

public class MyComparer : IComparer<Tuple<DateTime, double>> 
{ 
    public int Compare(Tuple<DateTime, double> x, Tuple<DateTime, double> y) 
    { 
     return x.Item1.CompareTo(y.Item1); 
    } 
} 

然后搜索

int index = myList.BinarySearch(new Tuple<DateTime, double>(timestamp, 0), 
            new MyComparer()); 

    if (index == 0) 
     // there is no items before timestamp 

    if (index > 0) 
     result = myList[index - 1]; // your item is previous 

    if (index < 0) // no tuple with date equal to timestamp 
     var nearestIndex = ~index; 
     if (nearestIndex > 0) 
      result = myList[nearestIndex - 1]; 
+0

@AlvinWong您不能使用带'IEnumerable'序列(也未排序)的二进制搜索。它枚举所有项目,但不使用内部存储来存储所有项目。它只需要一个最大项目。 –

+0

哦,看来我的大脑因为建议使用'SortedDictionary'的评论而感到困惑。似乎OP应该真的使用它并编写他自己的二进制搜索算法。 –

+0

@lazyberezovsky编译错误:MaxBy没有在System.Collections.Generic.IEnumerable << System.Tuple >>中定义。任何想法有什么不对? – Chris

0

myList.Where(t => t.Item1 < datetime).OrderByDescending(t => t.Item1).Last();

1
var result = myList.OrderByDescending(t => t.Item1) 
    .SkipWhile(t => t.Item1 > timestamp) 
    .First(); 
1

为了获得最佳的性能,你不应该使用LINQ的。二进制搜索给出了LINQ可以提供的O(n)的性能O(log n)intead。

你的类型创建一个比较器:

public class MyListComparer : IComparer<Tuple<DateTime, double>> { 

    public int Compare(Tuple<DateTime, double> x, Tuple<DateTime, double> y) { 
    return x.Item1.CompareTo(y.Item1); 
    } 

} 

使用带有BinarySearch method比较程序:

int idx = myList.BinarySearch(new Tuple<DateTime, double>(new DateTime(2013,2,8,21,34,0), 0), new MyListComparer()); 
if (idx < 0) { 
    idx = (~idx) - 1; 
} 
Tuple<DateTime, double> item = myList[idx]; 
+0

和有什么区别? –

+0

@lazyberezovsky:区别在于O(log n)小于O(n),因此性能更好。 – Guffa

+0

我询问了我和你的答案之间的区别:) MyListComparer vs MyComparer –