GroupBy()方法返回字典

问题描述 投票:0回答:1

我有一个名为Reservation的类,它具有StartDate和RoomNumber属性。然后,我有一个预订列表,其中我使用Linq查找有冲突的预订(冲突意味着一个预订的房号和开始日期与列表中的其他预订相同)

在下面的代码中,我使用GroupBy方法从列表中查找重复项。但是我需要返回一个Dictionary <>,由于GroupBy()方法,我不能再这样做了。如何访问预订类?

如何返回字典,因为现在我只能访问日期和数字属性,而不能访问Reservation类。主要课程:

return Reservations.GroupBy(i => new {i.StartDate, i.RoomNumber}).Where(g => g.Count)>1).Select(group => new {
   key=group.Key,
   value=group.ToList()
}).Select(f => new Dictionary <Reservation, List<Reservation>> (f.key, f.value);

教室

  public class Room
    {
        public int Number { get; set; }
        public int MaxPersonCount { get; set; }
        public bool IsDisabledFriendly { get; set; }
        public bool HasBalcony { get; set; }
        public bool IsInUse { get; set; }
        public bool HasAirConditioner { get; set; }
        public double Surface { get; set; }

        public bool Equals(Room other)
        {
            if (ReferenceEquals(null, other)) return false;
            if (ReferenceEquals(this, other)) return true;
            return Number == other.Number && MaxPersonCount == other.MaxPersonCount && IsDisabledFriendly == other.IsDisabledFriendly && HasBalcony == other.HasBalcony && IsInUse == other.IsInUse && HasAirConditioner == other.HasAirConditioner && string.Equals(Surface, other.Surface);
        }

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj)) return false;
            if (ReferenceEquals(this, obj)) return true;
            if (obj.GetType() != GetType()) return false;
            return Equals((Room)obj);
        }

        public override int GetHashCode()
        {
            unchecked
            {
                int hashCode = Number;
                hashCode = (hashCode * 397) ^ MaxPersonCount;
                hashCode = (hashCode * 397) ^ IsDisabledFriendly.GetHashCode();
                hashCode = (hashCode * 397) ^ HasBalcony.GetHashCode();
                hashCode = (hashCode * 397) ^ IsInUse.GetHashCode();
                hashCode = (hashCode * 397) ^ HasAirConditioner.GetHashCode();
                hashCode = (hashCode * 397) ^ Surface.GetHashCode();
                return hashCode;
            }
        }

        public override string ToString()
        {
            return $"{Number} ({MaxPersonCount} pers; {Surface} m2)";
        }
    }
}

课程预订

  public class Reservation
    {
        public int Id { get; set; }
        public Customer Customer { get; set; }
        public DateTime StartDate { get; set; }
        public DateTime EndDate { get; set; }
        public Room Room { get; set; }
        public int NoOfPersons { get; set; }

        public Reservation()
        {
        }

        public Reservation(int id, Customer customer, DateTime startDate, DateTime endDate, Room room)
        {
            if (endDate < startDate)
                throw new ArgumentException("The endDate value must be greater than startDate.", nameof(endDate));

            Id = id;
            Customer = customer ?? throw new ArgumentNullException(nameof(customer));
            Room = room ?? throw new ArgumentNullException(nameof(room));
            StartDate = startDate.Date;
            EndDate = endDate.Date;
        }

        public bool ConflictsWith(Reservation reservation)
        {
            return Room.Number == reservation.Room.Number &&
                   StartDate < reservation.EndDate &&
                   EndDate > reservation.StartDate &&
                   Id != reservation.Id;
        }

        public bool ConflictsWith(DateTime startDate, DateTime endDate)
        {
            return StartDate < endDate && EndDate > startDate;
        }
    }

例如:如果具有Id = 1的保留与具有Id = 2的保留和具有Id = 3的保留冲突,则我的词典将包含具有Id = 1的保留作为键和包含冲突保留的列表(具有Id 2和3)]

c# linq dictionary
1个回答
0
投票

更新问题后,您可以使用:OrderBy订购预定。GroupBy按日期和房间号分组。ToDictionary建立(预订,预订清单)字典,如以下代码:

Dictionary<Reservation, List<Reservation>> result = reservations.OrderBy(r => r.Id)
    .GroupBy(x => new { x.StartDate, x.Room.Number })
    .Where(x => x.Count() > 1)
    .ToDictionary(
        x => x.First(),
        y => y.Skip(1).ToList()
    );

用于测试:

List<Reservation> reservations = new List<Reservation>
{
    new Reservation {Id = 5, StartDate = DateTime.Now.Date, Room  = new Room{ Number = 4 }},
    new Reservation {Id = 3, StartDate = DateTime.Now.Date, Room  = new Room{ Number = 3 }},
    new Reservation {Id = 1, StartDate = DateTime.Now.Date, Room  = new Room{ Number = 2 }},
    new Reservation {Id = 2, StartDate = DateTime.Now.Date, Room  = new Room{ Number = 2 }},
    new Reservation {Id = 4, StartDate = DateTime.Now.Date, Room  = new Room{ Number = 2 }},
    new Reservation {Id = 6, StartDate = DateTime.Now.Date, Room  = new Room{ Number = 4 }}
};

Demo

foreach(var item in result)
{
    Console.WriteLine($"Key : Id::{item.Key.Id} : Number::{item.Key.Room.Number} ==> Values: ");
    foreach(var item1 in item.Value)
    {
        Console.WriteLine($"Id::{item1.Id} : Number::{item1.Room.Number}");
    }
}

结果

Key : Id::1 : Number::2 ==> Values:
Id::2 : Number::2
Id::4 : Number::2
Key : Id::5 : Number::4 ==> Values:
Id::6 : Number::4

我希望有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.