2012-10-03 166 views
2

我有一個類定義是這樣的:比較的對象,並返回列表

public class MyObjectModel 
{ 
    public int ObjectID { get; set; } 

    //for when the user's data is split in 2 fields 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 

    //for when the user's data is all in one field 
    public string FirstLastName { get; set; } 
} 

我有這些MyObjectModel的名單,我想,因爲這涉及到檢查,如果通過名稱與自定義排序過程中對它們進行排序該數據包含LastName(在這種情況下使用LastName排序)或FirstLastName(在這種情況下,我將打破字符串並對第二項進行排序,如果有的話,或者只有一個字,如果只有一個字)

我不確定兩件事:

  1. 應該使用IComparerIComparable
  2. 一旦它確定排序的順序(我可以做到這一點),我該如何做到這一點,以便該方法的輸出是代表ObjectID的整數列表。
+1

根據您使用的C#版本,您可以使用Linq對其進行排序。 –

+0

對於精度,我使用的是c#4. – frenchie

回答

3

使用LINQ:

List<MyObjectModel> objects = new List<MyObjectModel>(); 
    List<int> ids = objects.OrderBy(o => FunctionWhichReturnsNameForSort(o)).Select(o => o.ObjectID).ToList(); 

FunctionWhichReturnsNameForSort可以在另一個類中實現,或延伸,或者作爲一個部件。

// should be in a static helper class 
public static string NameForSort(this MyObjectModel obj) 
{ 
    if (!string.IsNullOrEmpty(obj.LastName)) return obj.LastName; 

    return obj.FirstLastName.Split(... // your splitting logic goes here 
} 

var ids = objects.OrderBy(o => o.NameForSort()).Select(o => o.ObjectID).ToList(); 
+0

FunctionWhichReturnsNameForSort函數應該返回什麼?它應該根據比較邏輯返回-1,0,1嗎? – frenchie

+0

它應該返回一個用於排序的名稱。我會添加一個例子。 –

+0

好的,謝謝。我將把這與霍特曼的答案結合起來! – frenchie

1

如果此排序是具體到一個用例,它可以使用LINQ實現:

var sortedIds = models.OrderBy(SecondName).Select(m => m.ObjectId).ToList(); 

private static string SecondName(MyObjectModel model) 
{ 
    if (!string.IsNullOrWhitespace(model.LastName)) return model.LastName; 
    return model.FirstLastName.Split(' ').Last(); 
} 
+0

某些姓氏有多個部分(空格)。 –

+0

在名稱字符串包含多個部分的情況下,我正在比較第二個字符串。 – frenchie

2

當你真正需要這個奇怪的雙重解決方案,那麼你會遇到類似這種問題更頻繁。作爲一個更通用的解決方案,考慮將業務邏輯名稱在幾個只讀屬性:

//for when the user's data is split in 2 fields 
public string FirstName { get; set; } 
public string LastName { get; set; } 

//for when the user's data is all in one field 
public string FirstLastName { get; set; } 

public string FullName 
{ 
    get { ... } // pick from LastName, FirstName, FirstLastName 
} 

public string SortName 
{ 
    get { ... } // pick from LastName, FirstLastName 
} 

一旦確定排序的順序(我能做到這一點),我該如何使它因此,該方法的輸出爲代表的ObjectID

result = MyObjectList 
      .OrderBy(m => m.SortName) // sort on SortName 
      .Select(m => m.ObjectID) // select the Id 
      .ToList(); 
+0

我喜歡這個想法:而不是在對象的屬性上進行比較,而是對返回我正在排序的字符串的函數的輸出進行比較。你是這個意思嗎? – frenchie

+0

是的。排序一個特殊的屬性,把它保存在你的班級裏面。 –

+0

好的,謝謝你的主意! – frenchie

1

雖然你可以使用LINQ INTS的列表,如其他人所說,這將涉及創建一個全新的列表,而不是突變的現有列表。這可能會或可能不會更好。如果要排序,很容易夠得列表本身:

List<string> list = new List<string>(){"a","b","c"}; 

list.Sort((a,b)=> a.CompareTo(b)); 

只要看看你的列表,通話Sort,並傳遞一個lambda,它有兩個項目,並返回一個整數,表示這是更大的。在你的情況下,只需在ab上調用一些方法來獲得一個字符串,然後在這兩個字符串上使用CompareTostring.Compare