2011-09-06 133 views
3

我在該列表中我繼續前進,隨機即添加不同類型的規則列表訂購項目<T>

IList<IRule> allRules = new List<IRule>() 

allRules.add(DeleteRule1) 
allRules.add(AddRule1) 
allRules.add(DeleteRule2) 
allRules.add(EditRule1) 
allRules.add(AddRule2) 
allRules.add(DeleteRule3) 

這一切工作正常,我努力的事要弄清楚的是,我需要對這個列表進行排序,以便它具有所有的AddRules,然後是EditRules,最後是DeleteRules。

任何人都可以指定我可以採取的方法嗎?

讓我知道如果這沒有意義,我會嘗試解釋更詳細。

非常感謝

+1

你已提供的IComparer 到allRules.Sort()方法或代替對比邏輯使用LambdaComparer與 – sll

+1

是否要保留每個類別中的現有訂單? (也就是說,你是否想要'A1 A2 E1 D1 D2 D3',或者'A2 A1 E1 D2 D2 D3 D1'確定)。 – AakashM

+0

'List 'ha a Sort method。 'IList '不(因此問題不同)。在示例中使用'List',在標題中使用'IList'。 – xanatos

回答

2

我假設你有三個類實現IRule(AddRule,EditRule,DeleteRule)。

如果您可以將IList的allRules類型更改爲List,則可以使用List<T>.Sort(Comparison<T>)方法。 Comparison是一個通用的委託與簽名

public delegate int Comparison<in T>(T x,T y) 

所以你需要的東西是這樣的:

public int IRuleComparer(IRule first, IRule second) 
{ 
    //build a table of type weights (this could be made static) 
    Dictionary<Type, int> typeWeights = new Dictionary<Type, int>(); 
    typeWeights.Add(typeof(AddRule), 1); 
    typeWeights.Add(typeof(EditRule), 2); 
    typeWeights.Add(typeof(DeleteRule), 3); 

    //get the types of the arguments 
    Type firstType = first.GetType(); 
    Type secondType = second.GetType(); 

    //are the types valid? 
    if (!typeWeights.ContainsKey(firstType)) 
    throw new Exception("invalid first type"); 

    if (!typeWeights.ContainsKey(secondType)) 
    throw new Exception("invalid second type"); 

    //compare the weights of the types 
    return typeWeights[firstType].CompareTo(typeWeights[secondType]); 
} 

另外,還要注意的是,排序實現使用快速排序算法,這不是一個穩定排序,即它可能會混淆AddRules的相對順序,所以在您的示例中,AddRule2可能會在AddRule1之前排序。


或者,你可以使用LINQ像這樣的東西:

public int GetRuleWeight(IRule item) 
{ 
    //build a table of type weights (this could be made static) 
    Dictionary<Type, int> typeWeights = new Dictionary<Type, int>(); 
    typeWeights.Add(typeof(AddRule), 1); 
    typeWeights.Add(typeof(EditRule), 2); 
    typeWeights.Add(typeof(DeleteRule), 3); 

    Type itemType = item.GetType(); 

    if (!typeWeights.ContainsKey(itemType)) 
    throw new Exception("invalid type"); 

    return typeWeights[itemType]; 
} 

allRules = allRules.OrderBy(item => GetRuleWeight(item)).ToList(); 

這將IList的(甚至IEnumerable的),所以你不會有改變allRules的類型。

+0

感謝您的意見:o) – Bobby

1

List has a sort method在那裏你可以通過一個可以爲你做比較算法的比較器。

using System; 
using System.Collections.Generic; 

public class Example 
{ 
    private static int MyRuleComparer(Rule x, Rule y) 
    { 
     // return -1, 0 or 1 by comparing x & y 
    } 

    public static void Main() 
    { 
     List<Rule> allRules= new List<Rule>(); 
     allRules.Add(...); 
     allRules.Add(...); 
     allRules.Add(...); 
     allRules.Add(...); 

     allRules.Sort(MyRuleComparer); 

    } 
} 

也作爲Sharique says,你可以使用SortedList類。這使用一個IComparer實例來完成這項工作:

using System; using System.Collections.Generic;

public class Example 
{ 
    public class MyComparer : IComparer { 
     int IComparer.Compare(Object x, Object y) 
     { 
      // return -1, 0 or 1 by comparing x & y 
     } 
    } 

    public static void Main() 
    { 
     SortedList allRules = new SortedList(new MyComparer()) 
     allRules.Add(...); // Sorted each time 
     allRules.Add(...); // Sorted each time 
     allRules.Add(...); // Sorted each time 
     allRules.Add(...); // Sorted each time 
    } 
} 
5

似乎沒有內置的方法來排序IList<T>

選項1:聲明變量爲List<T>類型的,並且使用List<T>.Sort Method

List<IRule> allRules = new List<IRule>(); 
allRules.add(DeleteRule); 
... 
allRules.Sort(); 

選項2:與被訂購了新的名單更換名單。

IList<IRule> allRules = new List<IRule>(); 
allRules.add(DeleteRule); 
... 
allRules = allRules.OrderBy(x => x).ToList(); 

選項3:實現快速排序的IList的<牛逼>。

選項4:選擇一種不同的集合類型,可以按照特定順序自動保持其元素。

0

List<T> Class比較操作:

列表不保證進行排序。在執行需要對 列表進行排序的操作(例如BinarySearch)之前,必須對列表 進行排序。

你可能想看看SortedList(但不是類型安全的),或添加某種或Order申請到IRule,然後進行排序使用IEnumerable<T>.OrderBy(...)

編輯

有一個generic version of SortedList

0

我會爲了簡單起見,因爲我猜測我們並沒有在這裏談論一個巨大的列表。

Assmptions:C#3,而適當的類或接口AddRuleEditRuleDeleteRule存在

var sortedRules = 
      allRules.OfType<AddRule>() 
    .Concat(allRules.OfType<EditRule>()) 
    .Concat(allRules.OfType<DeleteRule>());