2011-01-06 78 views
4

我是新來的lambda表達式,並且遇到了一些我不明白的東西。有人能告訴我爲什麼這種lambda排序表達式不起作用嗎?

我有像這樣的對象:

class MyListItem 
{ 
    string date; //date in the format "2010-12-05" 
    int Hour; //hour of day as an int 

} 

我有這些對象的列表,代表了一些日期和時間。

我要對此列表進行排序按日期和時間,讓我試試這個:

List<MyListItem> myList = new List<MyListItem>(); 

myList = getsomedata(); //populate list 

myList.Sort((a, b) => (a.date + a.Hour.ToString()).CompareTo(b.date + b.Hour.ToString())); 

和工程類的。問題是,時間是一個int,所以它有時候不是2位,造成一種像這樣:

2010-12-05 1 
2010-12-05 10 
2010-12-05 11 
2010-12-05 12 
2010-12-05 13 
2010-12-05 2 
2010-12-05 21 
2010-12-05 22 

我希望它是這樣的:

2010-12-05 1 
2010-12-05 2 
2010-12-05 10 
2010-12-05 11 
2010-12-05 12 
2010-12-05 13 
2010-12-05 21 
2010-12-05 22 

,所以我嘗試格式化字符串在我解析lambda之前添加一個零:

ret.Sort((a, b) => (a.date + a.Hour.ToString("00")).CompareTo(b.date + b.Hour.ToString("00"))); 

但它不會編譯。它告訴我:

Cannot convert lambda expression to type 'Systems.Collections.Generic.IComparer<MyListItem>' because it is not a delegate type. 

咦?在這種情況下,平原.ToString()(沒有格式字符串)和.ToString(「00」)有什麼不同?

此外,有關如何得到這個工作的任何建議?

+0

'ret`的類型是什麼?當我列出'List `時,我不會收到第二個排序例程的編譯問題。爲了再現性,您使用的是哪個版本的編譯器和框架? – Ani 2011-01-06 18:34:13

+0

奇怪你沒有編譯錯誤。 ret是列表()(應該是myList,剪切和粘貼錯誤)。我正在使用vs2010,.net 4.0。 – BDW 2011-01-06 20:13:05

回答

0

謝謝大家誰幫助。事實證明,問題是,在原來的班級,小時爲是空的,就像這樣:

class MyListItem 
{ 
    string date; //date in the format "2010-12-05" 
    int? Hour; //hour of day as an int 

} 

我使用的真正的類是生成的類比我給的例子大得多在這裏 - 我試圖縮短它澄清事情,並最終漏掉了相關部分。

更改排序使用可空INT作品的價值:

myList.Sort((a, b) => (a.date + a.Hour.Value.ToString("00")).CompareTo(b.date + b.Hour.Value.ToString("00"))); 

錯誤消息是沒有太大的幫助那裏,但每個人的工作的例子讓我追查。

2

原因是因爲它不是按順序排序,而是作爲一個字符串。您需要創建一個比較器來比較日期。看看排序 - 任何以1開頭的東西都以2開頭,因此您將得到:1,11,111,1111,2,22,222,223,333,333等。

嘗試將結果字符串轉換爲日期,這應該修復它。

DateTime.ParseExact(a.date + hour.ToString("00"), "yyyy-MM-dd HH", CultureInfo.InvariantCulture) 

應迴避關於()引起的ToString異常的編制問題。

+0

這對編譯問題有什麼影響? – Ani 2011-01-06 18:33:33

5

我不是在PC,所以我不能解釋第一個,但我回避它:

ret.Sort((a,b) => { 
    int result = string.Compare(a.date,b.date); 
    if(result==0) result = a.hour.CompareTo(b.hour); 
    return result; 
}); 

較少的字符串的創作,沒有分析費用等;)

1

它是因爲這些日期正在以它們的字符串形式進行比較。

您的通話拉姆達更改如下:

ret.Sort((a, b) => (DateTime.Parse(a.date + " " +a.Hour.ToString("00") 
+ ":00:00").CompareTo(DateTime.Parse(b.date + " " + b.Hour.ToString("00") + ":00:00"))); 
0

你可以變得瘋狂,並返回一個DateTime,結合現有油田的擴展方法 - 然後只是排序上。

所說邏輯也可以在排序表達式直接用爲好,但你沒有得到使用的擴展方法:)

公共靜態的DateTime GETDATE(這MyListItem myListItem) { 返回日期時間。解析(myListItem.date).AddHours(myListItem.Hour); }

2

我可以看到上面的代碼在格式化和非格式化的情況下工作得很好。我認爲沒有理由對這種錯誤的行爲

List<MyListItem> myList = new List<MyListItem>(); 

     getsomedata(myList); //populate list 

     myList.Sort((a, b) => (a.date + a.Hour.ToString("00")).CompareTo(b.date + b.Hour.ToString("00"))); 

    private void getsomedata(List<MyListItem> items) 
    { 
     for (int i = 1; i < 30; i += 3) 
     { 
      items.Add(new MyListItem("2010-12-05", i)); 
     } 
     for (int i = 2; i < 30; i += 3) 
     { 
      items.Add(new MyListItem("2010-12-05", i)); 
     } 
    } 

    class MyListItem 
    { 
     public MyListItem(string date, int hour) { this.date = date; this.Hour = hour; } 
     public string date; //date in the format "2010-12-05" 
     public int Hour; //hour of day as an int 
    } 
相關問題