2014-11-09 183 views
1

我需要按對象屬性中的一個排序對象列表,但它是一個需要排序的字符串,就好像它是一個整數。對象是屬性名稱(property.Name)爲字符串的自定義「屬性」對象,但90%的屬性名稱實際上是數字,而另外10%是名稱/字母(因此,變量本身必須是字符串而不是整數)。List <>按對象屬性排序

我知道我可以使用

propertyList.OrderBy(x => x.Name) 

...但如果它是一個字符串,將整理它看着它(即15000比20「大」)。

爲了排序的目的,我已經把列表分成兩個單獨的列表(一個包含所有包含字母的屬性名稱和另一個包含可以轉換爲整數的屬性名稱),但是我不'不知道如何對「整數」列表進行排序。

我試過這個,它不起作用,但有沒有這樣的事情,我可以使用?

propertyList.OrderBy(x => Convert.ToInt32(x.Name)) 
+2

您是否存儲'OrderBy(...)'的結果? 'OrderBy'不執行就地排序,而是返回一個排序的'IEnumerable '數據視圖。 – Dai 2014-11-09 06:04:49

+0

我編輯了你的標題。請參閱:「[應該在其標題中包含」標籤「](http://meta.stackexchange.com/questions/19190/)」,其中的共識是「不,他們不應該」。 – 2014-11-09 08:42:12

回答

4

您不需要將數據拆分爲兩個列表;也請注意,您可以執行拉姆達方法在複雜的操作,你只需要使用不同的語法:

IEnumerable<TItem> sorted = propertyList.OrderBy(x => { 
    Int32 asInt; 
    if(Int32.TryParse(x.Name, NumberStyles.Integer, CultureInfo.InvariantCulture, out asInt)) { 
     return asInt; 
    } 
    if(x.Name.Length > 0) return (Int32)x.Name[0]; 
    return 0; 
}); 

注意此代碼是有點醜陋和不完美的,因爲它不會排序兩個文本正確的名字,如果他們開始具有相同的性格。我建議使用的OrderBy而不是更先進的過載:

class NameComparer : IComparer<String> { 
    public Int32 Compare(String x, String y) { 
     // put Name comparison logic here 
    } 
} 

IEnumerable<TItem> sorted = propertyList.OrderBy(x => x.Name, new NameComparer()); 
0

目前還不清楚是什麼你真的想在這裏。你想要一個有序的視圖的原始數據?或者你是否真的想修改原始數據以便訂購?

如果是前者,那麼OrderBy()方法就是你想要的。這聽起來像你很好地將數字名稱與非數字名稱分開排序,但在這種情況下,當你嘗試第二個代碼示例時,「不工作」的含義並不清楚。該表達式應該可以正常工作,並且會提供數據的有序視圖。例如。

foreach (var x in propertyList.OrderBy(x => int.Parse(x.Name)) 
{ 
    // do something with the ordered elements 
} 

如果你的意思是你想實際訂購的原始數據,那麼你可以使用List<T>.Sort()方法:

propertyList.Sort((x, y) => int.Parse(x.Name).CompareTo(int.Parse(y.Name)); 

注意,在List<T>例如,從字符串轉換爲int是反覆完成。這對於相對較小的集合來說應該不成問題,但如果性能成爲問題,那麼使用LINQ OrderBy()方法(爲您緩存鍵)將是首選。您可以使用ToList()OrderBy()將結果轉化爲List<T>

當然,這涉及到中間數據結構的開銷,所以除非你有一個真正的演示性能問題來解決,否則你已經證明這個方案解決了這個問題。

+0

'請注意,在上面的兩個例子中,從字符串到int的轉換都是重複進行的:不是這樣的,'Enumerable.OrderBy'緩存鍵(至少這些天,至少它可能並不總是這樣做)。 – Rawling 2014-11-09 08:49:19

+0

啊,優秀。很高興知道......謝謝! – 2014-11-09 09:07:56