【问题标题】:Sorting an List<> with my custom order which is stored in another List (C#)?使用存储在另一个 List (C#) 中的自定义顺序对 List<> 进行排序?
【发布时间】:2010-11-07 18:46:08
【问题描述】:

谁能帮忙..我有一个像这样的通用列表

    IList<itemTp> itemTps;

itemTp 基本上是一个类(具有许多属性),其中一个属性是“代码”

我需要能够按照我在另一个列表中设置的特定顺序对其进行排序。

这个列表是一个简单的列表,列出顺序(从第一个到最后一个)就像说

代码1 代码3 代码2 代码5 (注意它从 1 到 3 到 2 到 5 - 这些是名称,它们可以被称为任何东西.. 重要的是顺序,它与数字没有任何关系)

基本上我需要确保 itemTp 中的项目根据其他列表中存在的内容进行排序...

所以想象我的 Ilist 是这样的 code1,code2,code3,code5 - 所以一旦排序完成 在我的

       IList<itemTp>

将包含 4 个按顺序排列的类,并具有 code1、code3、code2、code5 之类的属性(顺序更改)

任何想法如何做到这一点?

【问题讨论】:

    标签: c# .net visual-studio sorting


    【解决方案1】:

    您需要创建一个 IComparer,它将根据您的其他列表的状态比较项目。使用 IComparer 的优点是,如果需要优化,您将能够在类中构建缓存逻辑以避免重复 IndexOf() 查找。此外,您还可以维护多个“其他”列表,以便在适当时使用。

    class ItemTpComparer : IComparer<itemTp>
    {
        private IList<codeTp> otherList;
    
        public ItemTpComparer(IList<codeTp> otherList)
        {
            this.otherList = otherList;
        }
    
        public int Compare(itemTp a, itemTp b)
        {
            return otherList.IndexOf(a.Code) - otherList.IndexOf(b.Code);
        }
    }
    

    并执行排序:

    myList.Sort(new ItemTpComparer(otherList));
    

    【讨论】:

    • 我不会说有优势。您可以像传递接口一样将委托传递给实例方法,并在其中包含您想要的任何逻辑。
    • 这看起来很棒,只是一个问题,你正在将 a 和 b 传递给 otherList 上的 IndexOf ......所以如果我有“TestMeNow”和“TestMeLater”会发生什么...... Indexof 将返回每个6个没有??
    • 我不明白你的评论。如果 TestMeNow 和 TestMeLater 在其他列表中,它们都不能在索引 6 处。
    • @Groo:你可以有任何你想要的逻辑,真的,但是你必须在你的委托块之外定义一个字典来保存缓存的值等。定义一个 IComparer 可以让你封装那个逻辑进入一个类,执行排序将是代码中其他地方的一个自包含行。只是偏好问题。
    • 顺便说一下,IList 接口没有Sort 方法。不确定这是否是一个问题:问题标题说 List (它确实有一个 Sort 方法)但问题中的示例使用 IList.
    【解决方案2】:

    对不起,如果有问题,我这里没有安装 C# 编辑器,但它是这样的:

     Array.Sort(
         itemTps, 
         delegate(ItemTp a, ItemTp b)
         {
              return secondList.IndexOf(a.Code) - secondList.IndexOf(b.Code);
         });
    

    注意:这可能不是最有效的方法,而且根本没有检查第二个列表是否包含代码。

    [编辑] 正如 Mehrdad 所说,Array.Sort 不适用于通用 IList&lt;T&gt;。要对数组进行就地排序,您需要使用ArrayList.Adapter 方法创建一个包装器,然后对其进行排序。由于ArrayList.Sort 不支持委托比较,您需要将匿名委托放入IComparer&lt;T&gt; 的实现中。

    如果您需要在单独的列表中对其进行排序,那么通过首先创建一个数组来使用上述逻辑可能是有意义的。

    【讨论】:

    【解决方案3】:

    使用 C# 3 和 LINQ to Objects,我只需创建一个新列表,而不是尝试对现有列表进行排序:

    void Example()
    {
        IList<string> codes;
        IList<ItemTp> itemTps;
        itemTps = codes.Select(code => itemTps.Single(itp => itp.Code == code)).ToList();
    }
    

    【讨论】:

      猜你喜欢
      • 2015-01-02
      • 2017-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-18
      • 1970-01-01
      • 2016-06-26
      • 2018-10-28
      相关资源
      最近更新 更多