0

I have a class called Reservation that has the properties StartDate and RoomNumber. Then I have a list Reservations in which I use Linq to find reservations that have conflicts (A conflict means that a reservation has the same room number and start date as other reservations in the list)

In the following code, I used the GroupBy method to find the duplicates from the list. But I need to return a Dictionary<> which I can not longer do because of the GroupBy() method. How can I access the Reservation class?

How can I return the Dictionary, because right now I can only access the date and number properties, not the Reservation class. Class main:

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);

For example: if Reservation with Id=1 has conflicts with Reservations with Id=2 and with Reservation with Id=3 then my Dictionary will contain Reservation with Id=1 as key and a List containing the reservations in conflict (with Id 2 and 3)

gameloverr
  • 53
  • 1
  • 8
  • https://stackoverflow.com/a/954086/490282 – Oliver Apr 23 '20 at 15:29
  • 1
    ``return Reservations.GroupBy(i => new {i.StartDate, i.RoomNumber}) .Where(g => g.Count > 1) .ToDictionary(k=>k.Key, v=>v.ToList());`` – Mohammed Sajid Apr 23 '20 at 16:09
  • If I understood you, you want to use one of the duplicate reservations of each group as a key, right? Which of the duplicate reservations (for example, with max or min *StartDate*) must be used as a key? – Iliar Turdushev Apr 23 '20 at 16:15
  • What is wrong with the code shown? – NetMage Apr 23 '20 at 16:18
  • @Sajid Yes I want to use every reservation from the group that has duplicates as a key along with the list of reservations that are duplicates for that key – gameloverr Apr 23 '20 at 16:40
  • @NetMage In my code I want to return a `Dictionary>` First Parameter will be Reservation class that has duplicates and second parameter will be the list of all duplicates. In my code the key is either start date or roomNumber given by the GroupBy method – gameloverr Apr 23 '20 at 16:45
  • The class ``reservation`` contains just ``StartDate`` and ``RoomNumber`` properties? – Mohammed Sajid Apr 23 '20 at 17:36
  • ```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; }``` – gameloverr Apr 23 '20 at 17:47
  • class Reservation also contains these methods – gameloverr Apr 23 '20 at 17:47
  • 1
    @gameloverr after posting the ``ConflictsWith`` i think the ``Reservation`` class contains also ``EndDate``, ``Id`` and ``Room``, so this not exactly what have posted like a question? there is a problem here: if the reservation id=1 and Id=2 are in conflict and gives 2 grouped reservations. so the key will be reservation 1 or 2? it's not clear, you can add all classes and example with expected result in the question to help us understand what you want. – Mohammed Sajid Apr 23 '20 at 18:03
  • Please improve your question rather than post comments. – NetMage Apr 23 '20 at 18:08
  • I added the Reservation and Room classes – gameloverr Apr 23 '20 at 18:46
  • This code is all you need to find duplicates and to deal with them. It's not necessary to create a dictionary. – Gert Arnold Apr 23 '20 at 19:50

1 Answers1

1

After updating the question, you can use :
OrderBy to order the reservations.
GroupBy to group by date and Room number.
ToDictionary to build a dictionary of (reservation, list of reservation), like the following code:

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()
    );

For test :

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}");
    }
}

Result

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

I hope this help.

Mohammed Sajid
  • 4,778
  • 2
  • 15
  • 20