【问题标题】:Custom List Sort by multiple conditions自定义列表按多个条件排序
【发布时间】:2023-03-26 13:26:01
【问题描述】:

我有一个带有字符串字段的类,我想使用多个条件对其进行排序。

有问题的班级

class Items
{
    public string ItemType {get; set;}
    public string Code {get; set;}

    // other members elided

    public Items(string _IT, string _Cd)
    {
        ItemType = _IT;
        Code = _Cd;
    }
}

使用类

List<Items> lstItemCol = new List<Items>();

lstItemCol.Add(new Items("EE", "12345"));
lstItemCol.Add(new Items("WW", "5881"));
lstItemCol.Add(new Items("LLL", "215458"));
lstItemCol.Add(new Items("WW", "789"));
lstItemCol.Add(new Items("EE", "582"));

我想要做的是对列表进行排序,以便项目按 EE 排序,然后是 WW,然后是 LLL

输出顺序应该是:

"EE", "582"
"EE", "12345"
"WW", "5881"
"WW", "789"
"LLL", "215458"

我想不出一种优雅的方式来做到这一点,然后将另一个字段添加到类 (sortOrder) 并对此进行排序:我宁愿避免这种情况,只对 ItemType 进行排序?

【问题讨论】:

  • 查看List&lt;T&gt;.Sort() 的重载。使用自定义比较。
  • 您会很高兴创建一个按您想要的方式排序的列表吗?如果是这样,LINQ 绝对是要走的路。否则,自定义比较应该不会太难......
  • 您的排序顺序不清楚。特别是当 ItemType 相等时如何对项目进行排序
  • 你可以试试这个:lstItemCol.Sort((x, y) => x.ItemType != y.ItemType ? x.ItemType.CompareTo(y.ItemType) : x.Code.CompareTo( y.代码));
  • 应该说我使用的是 .Net 2.0 所以我不能使用 LINQ

标签: c# list sorting .net-2.0


【解决方案1】:

有两种方法可以以可重用和干净的方式实现这一点。

  1. 在项目上实现IComparable

  2. 创建您自己的项目比较器,并将其用作参数来订购 linq。

PS:我还建议对类名 Item 使用单数形式,而不是复数形式的 Items。项目通常是指集合。

PPS:我还用linqpad 来演示实现。

void Main()
{
    var lstItemCol = new List<Item>();

    lstItemCol.Add(new Item("EE", "12345"));
    lstItemCol.Add(new Item("WW", "5881"));
    lstItemCol.Add(new Item("LLL", "215458"));
    lstItemCol.Add(new Item("WW", "789"));
    lstItemCol.Add(new Item("EE", "582"));

    lstItemCol.OrderBy(ic => ic).Dump();
    lstItemCol.OrderBy(ic => ic, new ItemComparer()).Dump();
}

// Define other methods and classes here

class Item : IComparable<Item>, IComparable
{
    public string ItemType { get; set; }
    public string Code { get; set; }

    // other members elided

    public Item(string _IT, string _Cd)
    {
        ItemType = _IT;
        Code = _Cd;
    }

    public int CompareTo(Item other)
    {
        if (other == null) return 1;
        var result = ItemType.Length.CompareTo(other.ItemType.Length);
        if (result == 0) result = ItemType.CompareTo(other.ItemType);
        if (result == 0) result = Code.Length.CompareTo(other.Code.Length);
        if (result == 0) result = Code.CompareTo(other.Code);
        return result;
    }
    int IComparable.CompareTo(object other)
    {
        return CompareTo(other as Item);
    }
}

sealed class ItemComparer : FComparer<Item>
{
    private static readonly Func<Item, Item, int> _comparer = (v1, v2) =>
    {
        var result = v1.ItemType.Length.CompareTo(v2.ItemType.Length);
        if (result == 0) result = v1.ItemType.CompareTo(v2.ItemType);
        if (result == 0) result = v1.Code.Length.CompareTo(v2.Code.Length);
        if (result == 0) result = v1.Code.CompareTo(v2.Code);
        return result;
    };

    public ItemComparer()
        :base(_comparer)
    { }
}

abstract class FComparer<T> : IComparer<T>
{
    private readonly Func<T, T, int> _comparer;

    protected FComparer(Func<T, T, int> comparer)
    { _comparer = comparer; }

    public int Compare(T v1, T v2)
    {
        return _comparer(v1, v2);
    }
}

【讨论】:

  • 附带说明,您也可以在列表中使用 .Sort,因为 Item 实现了 IComparable。如果没有 linq,它将按需要工作。
猜你喜欢
  • 2019-02-28
  • 2019-03-19
  • 2021-04-02
  • 2017-07-30
  • 2014-12-09
  • 1970-01-01
  • 2013-09-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多