33

I have a nested list, something like this:

List<Hotel> Hotels;

public class Hotel
{
    List<RoomType> RoomType;
}

public class RoomType
{
    Room Room;
}

public class Room
{
    int RoomId;
}

It's a little convoluted, sorry couldn't think of a better mockup model. The Idea is that I have many hotels, each hotels has many room types, and assume each room type has exactly one room object.

Now from Hotels list, I just want to select all RoomId's.. I am stuck here, while trying to nest all list..

right now, I am trying this:

//cant do this some invalid error
int[] AllRoomIds = Hotels.selectMany(x => x.Rooms)
                       .selectMany(y => y.RoomType.Room.Id).Distinct().ToArray()

//cant do this - z doesnt have anything
int[] AllRoomIds = Hotels.selectMany(x => x.Rooms)
                         .selectMany(y => y.RoomType)
                         .select(z => z. 

How do I do this please?

Accessing all id's of all items in a nested list.. occasionally it complains of cannot convert int to boolean and I do not know what it means...

Thanks.. hope the question was understanble

LocustHorde
  • 6,361
  • 16
  • 65
  • 94
  • 1
    Does this answer your question? [Get All Children to One List - Recursive C#](https://stackoverflow.com/questions/19237868/get-all-children-to-one-list-recursive-c-sharp) – Michael Freidgeim Jun 03 '20 at 00:26

3 Answers3

54

While the hierarchy you posted above really doesn't make much sense to me (seems RoomType and Room are backwards), I'll post an example to go with it:

Hotels.SelectMany(h => h.RoomType)
      .Select(rt => rt.Room.Id)
      .Distinct()
      .ToArray();
Justin Niessner
  • 242,243
  • 40
  • 408
  • 536
  • I think OP needs to get the IDs from the Hotel.Rooms collection – James Johnson Sep 09 '11 at 15:14
  • @James - So do I, but the class definitions that the OP posted above don't match the LINQ queries. I'm going off of the classes posted above. I added a note to my answer that mentions that the classes seem backwards. – Justin Niessner Sep 09 '11 at 15:15
  • @Justin, Sorry, this isn't even related to my model I just wanted to make something up out of thin air - only to say I need to select id in a nested list, so just wrote this without thinking through. – LocustHorde Sep 09 '11 at 15:17
  • @Justin, yea this works! I now wonder why I was trying a ``selectMany`` the second time around instead of just a ``select`` - may be it's cause I've had a couple of beer as a send off party of a colleague this afternoon! Thanks for the help! – LocustHorde Sep 09 '11 at 15:18
11

Sounds like you need a Select for the RoomType.Room.Id rather than SelectMany. Using the Query syntax (which I typically prefer over lambda syntax for SelectMany, it would be

var query = (from hotel in Hotels
            from type in Hotel.RoomType
            select type.Room.Id)
            .Distinct.ToArray();

Here you have a SelectMany between Hotels and Roomtype, but not one between type and Room.

Jim Wooley
  • 10,169
  • 1
  • 25
  • 43
  • Hi, is there a reason you prefer query syntax instead of lambda? and you are right, I just needed a ``select``, instead of ``selectmany`` – LocustHorde Sep 09 '11 at 15:20
  • I just find the query syntax more human readable for SelectMany and Group coming from a SQL world. It's all personal preference I suppose. Consider the examples at [link](http://www.thinqlinq.com/Post.aspx/Title/Select-Many-with-Rx-and-RxJs) comparing the Rx SelectMany with query expressions vs the same with lambdas as an example with a moderately complex example. – Jim Wooley Sep 09 '11 at 15:30
0

Here is another approach using GroupBy (without Distinct):

int[] allRoomIds = Hotels.SelectMany(h => h.RoomType)
      .GroupBy(rt => rt.Room.Id)
      .Select(room => room.Room.Id)
      .ToArray();

If you will need the list of object:

List<Room> allRooms = Hotels.SelectMany(h => h.RoomType)
     .GroupBy(rt => rt.Room.Id)
     .Select(room => room.First())
     .ToList();
Shahar Shokrani
  • 7,598
  • 9
  • 48
  • 91