2013-02-05 50 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 –