[英]Can someone tell me why this lambda sort expression doesn't work?
我是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”)之間有什么不同?
另外,有關如何使這項工作的任何建議?
我不是在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開頭的任何東西都以2開頭,因此你會得到:1,11,111,1111,2,22,222,222,3,33,333等。
嘗試將結果字符串轉換為日期,應該修復它。
DateTime.ParseExact(a.date + hour.ToString("00"), "yyyy-MM-dd HH", CultureInfo.InvariantCulture)
應該回避有關ToString()引起的異常的編譯問題。
我可以看到上面的代碼在使用和不使用格式時都能正常工作。 我認為沒有理由這樣的錯誤行為
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
}
這是因為日期以字符串形式進行比較。
將lambda調用更改為:
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")));
你可能會變得瘋狂並制作一個返回DateTime的擴展方法,將現有字段組合在一起 - 然后對其進行排序。
所述邏輯也可以直接在排序表達式中使用,但是你不能使用擴展方法:)
public static DateTime GetDate(this MyListItem myListItem){return DateTime.Parse(myListItem.date).AddHours(myListItem.Hour); }
感謝所有幫助過的人。 事實證明,問題是在原始類中,小時是可以為空的,如下所示:
class MyListItem
{
string date; //date in the format "2010-12-05"
int? Hour; //hour of day as an int
}
我正在使用的真正的類是一個比我在這里給出的例子大得多的生成類 - 我試圖將其縮短以澄清事情,最后省略了相關部分。
更改排序以使用nullable int的值:
myList.Sort((a, b) => (a.date + a.Hour.Value.ToString("00")).CompareTo(b.date + b.Hour.Value.ToString("00")));
錯誤信息在那里沒什么幫助,但每個人的工作示例都允許我跟蹤它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.