2011-09-06 110 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>());