需要更好的方法来对一个列表和另一个列表进行排序

本文关键字:列表 一个 另一个 排序 更好 方法 | 更新日期: 2023-09-27 18:04:38

我有两个列表-一个来宾列表和一个VIP列表。我需要对来宾列表进行排序,以便如果它包含VIP列表上的第一个人,他们将进入列表的顶部,依此类推。在贵宾名单排完后,其余的客人名单保持原来的顺序。排序必须同时使用名字和姓氏。我已经使用List和foreach语句完成了这一点,但似乎应该有一种更优雅的方式。

有没有更简单、更现代的方法来做这种排序?

class Guest 
{
    public int NumberInParty { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}
class VIP
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}
class TrackedGuest
{
    public Guest guest;
    public bool isTaken;
    public TrackedGuest(Guest g)
    {
        this.guest = g;
        isTaken = false;
    }
}
static void Main(string[] args)
{
    List<Guest> guests = new List<Guest>();
    guests.Add(new Guest { FirstName = "Rob", LastName = "Carson", NumberInParty = 5 });
    guests.Add(new Guest { FirstName = "George", LastName = "Waverly", NumberInParty = 3 });
    guests.Add(new Guest { FirstName = "Pete", LastName = "Spacely", NumberInParty = 2 });
    guests.Add(new Guest { FirstName = "George", LastName = "Jetson", NumberInParty = 6 });
    guests.Add(new Guest { FirstName = "Cosmo", LastName = "Spacely", NumberInParty = 2 });
    List<VIP> vips = new List<VIP>();
    vips.Add(new VIP { FirstName = "George", LastName = "Jetson" });
    vips.Add(new VIP { FirstName = "Cosmo", LastName = "Spacely" });
    List<TrackedGuest> TrackedGuests = new List<TrackedGuest>();
    foreach (Guest g in guests)
    {
        TrackedGuests.Add(new TrackedGuest(g));
    }
    List<Guest>SortedGuests = new List<Guest>();
    // Copy each guest on the VIP list in order
    foreach (VIP vip in vips)
    {
        foreach (TrackedGuest tGuest in TrackedGuests)
        {
            if (
                (tGuest.isTaken == false) &&
                (vip.FirstName == tGuest.guest.FirstName) &&
                (vip.LastName == tGuest.guest.LastName)
                )
            {
                SortedGuests.Add(tGuest.guest);
                tGuest.isTaken = true;
            }
        }        
    }
    // Process the rest of the guests
    if (SortedGuests.Count < guests.Count)
    {
        foreach (TrackedGuest tGuest in TrackedGuests)
        {
            if (tGuest.isTaken == false)
            {
                SortedGuests.Add(tGuest.guest);
                tGuest.isTaken = true;
            }
        }
    }
    foreach (Guest guest in SortedGuests)
    {
        Console.WriteLine(guest.FirstName + " " + guest.LastName + ": " + guest.NumberInParty + " in party.");
    }
    Console.ReadLine();
}

需要更好的方法来对一个列表和另一个列表进行排序

var sorted = new List<Guest>();
var guestvips = from g in guests
                from v in vips.Where(vip => vip.FirstName == g.FirstName && vip.LastName == g.LastName).DefaultIfEmpty()
                where v != null
                select g;
var guestsimple = from g in guests
                  from v in vips.Where(vip => vip.FirstName == g.FirstName && vip.LastName == g.LastName).DefaultIfEmpty()
                  where v == null
                  select g;
sorted.AddRange(guestvips.Concat(guestsimple));

此代码'左加入'客人在vip两次。在第一种情况下,它接收贵宾相等的客人,第二种情况下,没有贵宾相等的客人。第一个大小写实际上可以用'join'关键字重写

// dictionary to easily get vips order
// uses anonymous types, to get value equality for free
var vipsOrder = vips.Select((v, i) => new { v, i })
                    .ToDictionary(x => new { x.v.FirstName, x.v.LastName },
                                  x => x.i);
// sort first by order taken from vipsOrder and then by name
var sortedGuests = (from g in guests
                    let info = new { g.FirstName, g.LastName }
                    let oorder
                     = vipsOrder.ContainsKey(info)
                         ? vipsOrder[info] : vips.Count
                    orderby oorder, info.FirstName, info.LastName
                    select g).ToList();