如何排序列表

本文关键字:列表 排序 何排序 | 更新日期: 2023-09-27 18:06:58

如何根据会员角色对以下客户列表进行排序,例如首先是金客户,然后是银客户,其余的则按他们的名字&Lastname。

public class  Customer
{
    public string id { get; set; }
    public string Firstname { get; set; } 
    public string Lastname { get; set; }
    public string memberRole { get; set; } // Golden and Silver 
}
List<Customer> customers = new List<Customer>();

如何排序列表

customers.OrderBy(c => 
   c.memberRole == "Golden" ? 0 : (c.memberRole == "Silver" ? 1 : 2))
 .ThenBy(c => c.FirstName)
 .ThenBy(c => c.LastName)

您可以使用OrderByDescending与一个bool,其中true 高于false:

customers  = customers 
    .OrderByDescending(c => c.memberRole == "Golden")
    .ThenBy(c => c.Firstname)
    .ThenBy(c => c.LastName)
    .ToList();

从设计的角度来看,最好将成员角色比较放在单独的类中。通过这种方式,您可以轻松地重用它,进行单元测试,并在出现新角色时进行升级。为了与LINQ兼容,最好实现IComparer类。

public class MemberRoleComparison : IComparer<string>
{
    // Put in required order from most importan to less
    internal static readonly string[] ROLES = { "Golden", "Silver", "Bronze" };
    int IComparer<string>.Compare(string x, string y)
    {
        return Array.IndexOf(ROLES, x).CompareTo(Array.IndexOf(ROLES, y));
    }
}

那么排序将看起来像:

var sorted = customers
    .OrderBy(item => item.memberRole, new MemberRoleComparison())
    .ThenBy(c => c.Firstname)
    .ThenBy(c => c.Lastname)
;

如果规范允许,您可能希望将角色的字符串表示形式替换为enum。

public enum MemberRole
{
    Golden = 1,
    Silver = 2,
    Bronze = 3
}

那么你可以像"customer1"那样直接比较角色。memberRole> customer2.memberRole".

如果你想优化速度和内存消耗(通常快30-40%),最好使用List。排序例程。首先定义客户比较可重用类:

public class CustomerComparison : IComparer<Customer>
{
    private IComparer<string> _RoleComparer = new MemberRoleComparison();
    int IComparer<Customer>.Compare(Customer x, Customer y)
    {
        int result = _RoleComparer.Compare(x.memberRole, y.memberRole);
        result = result == 0 ? string.Compare(x.Firstname, y.Firstname) : result;
        return result == 0 ? string.Compare(x.Lastname, y.Lastname) : result;
    }
}

然后使用现有列表的Sort方法:

customers.Sort(new CustomerComparison());

但是为了更好的性能,你可能想使用并行LINQ:

var sorted = customers
    .AsParallel()
    .OrderBy(item => item.memberRole, new MemberRoleComparison())
    .ThenBy(c => c.Firstname)
    .ThenBy(c => c.Lastname)
;
var result = customers
    .Select(z => new
        {
            OrderableRole = role == "Golden"
                ? 1
                : role == "Silver"
                    ? 2
                    : int.MaxValue,
            Customer = z
        })
    .OrderBy(z => z.OrderableRole)
    .ThenBy(z => z.Customer.Firstname)
    .ThenBy(z => z.Customer.LastName)
    .ToList();