简体   繁体   English

在IList中订购商品<T>

[英]Ordering items in IList<T>

I have a list 我有一份清单

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

in that list i go ahead and add different type of rules at random ie 在该列表中,我继续并随机添加不同类型的规则,即

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

all this works fine the thing i am trying to figure out is that i need this list to be sorted so it has all the AddRules first then EditRules and finally DeleteRules. 所有这一切工作正常,我想弄清楚的是,我需要这个列表进行排序,所以它首先有所有的AddRules然后EditRules,最后是DeleteRules。

Can any one specify an approach I can take ? 任何人都可以指定我可以采取的方法吗?

Let me know if this does not make sense and I will try to explain in more detail. 如果这没有意义,请告诉我,我会尝试更详细地解释。

Many Thanks 非常感谢

There doesn't seem to be a built-in way to sort an IList<T> . 似乎没有一种内置的方法来排序IList <T>

Option 1 : Declare the variable to be of type List<T> and use the List<T>.Sort Method . 选项1 :将变量声明为List <T>类型,并使用List <T> .Sort方法

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

Option 2 : Replace the list with a new list that is ordered. 选项2 :使用订购的新列表替换列表。

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

Option 3 : Implement quick-sort for IList<T>. 选项3 :为IList <T>实现快速排序。

Option 4 : Choose a different collection type that automatically keeps its elements in a certain order. 选项4 :选择一种不同的集合类型,自动将其元素保持在特定顺序。

There is a SortedList class which might be what your are looking for 有一个SortedList类可能正是您正在寻找的

您应该实现自己的IComparer,而不是在Sort方法中使用它。

I assume that you have three classes that implement IRule (AddRule, EditRule, DeleteRule). 我假设您有三个实现IRule的类(AddRule,EditRule,DeleteRule)。

If you can change the type of allRules from IList to List, you can use the List<T>.Sort(Comparison<T>) method. 如果可以将所有规则的类型从IList更改为List,则可以使用List<T>.Sort(Comparison<T>)方法。 Comparison is a generic delegate with the signature 比较是具有签名的通用委托

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

so you'll need something like this: 所以你需要这样的东西:

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]);
}

Also, take note that the Sort implementation uses the quick sort algorithm, that is not a stable sort, ie it might mess the relative order of AddRules, so in your example, AddRule2 could get sorted before AddRule1. 另外,请注意Sort实现使用快速排序算法,这不是一个稳定的排序,即它可能会混乱AddRule的相对顺序,因此在您的示例中,AddRule2可以在AddRule1之前进行排序。


Alternatively, you could use LINQ with something like this: 或者,你可以使用这样的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();

this will work with IList (even with IEnumerable), so you wont have to change the type of allRules. 这将适用于IList(即使使用IEnumerable),因此您不必更改allRules的类型。

List has a sort method where you can pass a comparator that can do the comparison algorithm for you. List有一个sort方法 ,你可以通过一个可以为你做比较算法的比较器。

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);

    }
}

Also as Sharique says , you could use a SortedList class. 同样,Sharique ,你可以使用SortedList类。 This uses an IComparer instance to do the work: 这使用IComparer实例来完成工作:

using System; 使用系统; using System.Collections.Generic; 使用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
    }
}

a simplistic approach is to create 3 separate lists for each type then copy items back to the list from AddRulesList then EditRulesList ..etc, this is fast and only requires too loops. 一种简单的方法是为每种类型创建3个单独的列表,然后将项目从AddRulesList和EditRulesList ..etc复制回列表,这很快,只需要太循环。

if you want to be generic and rely on built in sorting capabilities you will need to implement comparison operation for the IRule type 如果你想成为通用的并依赖于内置的排序功能,你需要实现IRule类型的比较操作

http://codebetter.com/davidhayden/2005/03/06/implementing-icomparer-for-sorting-custom-objects/ http://codebetter.com/davidhayden/2005/03/06/implementing-icomparer-for-sorting-custom-objects/

List<T> Class : List<T> Class

The List is not guaranteed to be sorted. 列表不保证排序。 You must sort the List before performing operations (such as BinarySearch) that require the List to be sorted. 您必须在执行需要对列表进行排序的操作(例如BinarySearch)之前对List进行排序。

You might want to look at the SortedList (but it is not type safe), or add some kind or Order filed to IRule , then sort using IEnumerable<T>.OrderBy(...) . 您可能希望查看SortedList (但它不是类型安全的),或者向IRule添加一些类型或Order ,然后使用IEnumerable<T>.OrderBy(...)进行排序。

Edit 编辑

There is a generic version of SortedList . 有一个通用版本的SortedList

I would go for simplicity, since I'm guessing that we're not talking about a huge list here. 我会说简单,因为我猜我们不是在谈论一个巨大的列表。

Assmptions: C# 3, and that appropriate classes or interfaces AddRule , EditRule , DeleteRule exist Assmptions:C#3,并且存在适当的类或接口AddRuleEditRuleDeleteRule

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM