我有两个列表 - 访客列表和VIP列表。我需要对Guest列表进行排序,以便如果它包含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();
}
答案 0 :(得分:4)
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));
此代码&#39;离开加入&#39;客人点了两次。在第一种情况下,它需要那些具有相同VIP的客户,其次是那些没有相同VIP的客户。第一种情况可以通过&#39; join&#39;重写。实际上是关键字。
答案 1 :(得分:0)
// 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();