如何正确使用thenBy进行排序C# linq?

z8dt9xmd  于 2022-12-06  发布在  C#
关注(0)|答案(3)|浏览(159)

我有类人

public class Person 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public string VisitPlace { get; set; } 
}

我有这个班的名单

List<Person> list = new List<Person>()
{
    new Person { FirstName = "Name1", LastName = "Smith", VisitPlace = "London; Paris" },
    new Person { FirstName = "Name2", LastName = "Smith", VisitPlace = "Berlin" },
    new Person { FirstName = "Name3", LastName = "Smith", VisitPlace = "London; Berlin" },
    new Person { FirstName = "Name4", LastName = "Smith", VisitPlace = "Berlin" },
    new Person { FirstName = "Name5", LastName = "Smith", VisitPlace = null },
    new Person { FirstName = "Name6", LastName = "Smith", VisitPlace = "Paris" },
    new Person { FirstName = "Name7", LastName = "Smith", VisitPlace = null },
    new Person { FirstName = "Name8", LastName = "Smith", VisitPlace = "Paris; London" },
    new Person { FirstName = "Name9", LastName = "Smith", VisitPlace = "London" },
};

我想对这个列表进行排序:

  • 参观伦敦广场的人
  • 参观巴黎广场的人
  • 访问柏林的人(如果一个人有两个访问地点,例如(访问地点=伦敦;巴黎)那么重要的只是第一名)
  • visitPlace = null的所有人员-位于列表末尾
var list2 = list.OrderByDescending(x => x.VisitPlace).ThenByDescending(x => x.VisitPlace == "London").ThenBy(x => x.VisitPlace == "Paris").ThenBy(x => x.VisitPlace == "Berlin");

更正列表中的人员:人员1、人员3、人员9、人员6、人员8、人员2、人员4、人员5、人员7
它是排序的,但只是orderbyDescending。然后By不起作用。
为什么thenBy不起作用?我怎样才能用linq正确地排序呢?

2ledvvac

2ledvvac1#

这对我很有效:

var list2 = list
    .OrderBy(x => x.VisitPlace?.Split(';').First() == "London")
    .ThenBy(x => x.VisitPlace?.Split(';').First() == "Paris")
    .ThenBy(x => x.VisitPlace?.Split(';').First() == "Berlin")
    .ThenByDescending(x => x.FirstName)
    .Reverse()
    .ToList();
idfiyjo8

idfiyjo82#

这对我很有效:

var priority = new [] { "London", "Paris", "Berlin" };

var list2 =
    list
        .OrderBy(x =>
            x.VisitPlace == null
            ? priority.Length
            : Array.IndexOf(priority, x.VisitPlace.Split(';')[0]))
        .ToList();

它给出:

更可靠的版本如下:

var list2 =
(
    from person in list
    let firstVisitPlace =
        person.VisitPlace == null
        ? null
        : person.VisitPlace.Split(';')[0]
    let position =
        priority.Contains(firstVisitPlace)
        ? Array.IndexOf(priority, firstVisitPlace)
        : priority.Length
    orderby position
    select person
).ToList();
s8vozzvw

s8vozzvw3#

这对我很有效:
我将把逻辑移到一个专用的方法中,如下所示:

foreach (var item in people.OrderBy(MyMagicOrder))
{
    Console.WriteLine($"{item.FirstName} | {item.VisitPlace}");
}

int MyMagicOrder(Person p)
{
    if (string.IsNullOrEmpty(p.VisitPlace))
        return 4;
    
    var split = p.VisitPlace.Split(";", StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
    var firstVisitPlace = split.First();
    if (firstVisitPlace == "London")
        return 0;
    if (firstVisitPlace == "Paris")
        return 1;
    if (firstVisitPlace == "Berlin")
        return 2;
    
    return 3;
}

在这里,您可以看到一个有效的解决方案:
https://dotnetfiddle.net/50kYS2

相关问题