Reputation: 196669
I have a list of Room objects, each room object has a Building attribute;
public class Room
{
public string BuildingName;
public string Name
}
I now want to filter my collection where i only take 1 room from each building (I don't care which one)
so for example
var room = new Room(){BuildingName ="Building 1", Name = "Room 1"};
var room2 = new Room(){BuildingName ="Building 1", Name = "Room 2"};
var room3 = new Room(){BuildingName ="Building 2", Name = "Room 3"};
var room4 = new Room(){BuildingName ="Building 2", Name = "Room 4"};
var room5 = new Room(){BuildingName ="Building 2", Name = "Room 5"};
var ListofRooms = new List<Room> {room, room2, room3, room4, room5};
in this case i would want to run this list through a function that would return an array with 2 items (one from each Building)
Upvotes: 3
Views: 202
Reputation: 3005
You could use this approach:
var result = ListofRooms.Distinct(new BuildingEqualityComparer());
And the class BuildingEqualityComparer
is as follows:
public class BuildingEqualityComparer : IEqualityComparer<Room>
{
public bool Equals(Room x, Room y)
{
return x.BuildingName.Equals(y.BuildingName);
}
public int GetHashCode(Room obj)
{
return obj.BuildingName.GetHashCode();
}
}
This approach is actually rarelly used because you need to make an implementation of IEqualityComparer
which is a PITA, but it's just another way of achieving what you need, so if you like it or find it simpler, use it!!!
Upvotes: 0
Reputation: 113442
LINQ is pretty convenient for this sort of task:
var result = ListofRooms.GroupBy(room => room.BuildingName)
.Select(buildingGroup => buildingGroup.First())
.ToList();
What this does is create a bucket for each building (consisting of the rooms in the building), then select a room from each bucket, before finally materializing the selected rooms into a collection.
Some tangential points:
listOfRooms
), not PascalCase(ListofRooms
).new Room { BuildingName = "Building 1", Name = "Room 1" }
If you don't want to use LINQ for this, I would do:
var seenBuildingNames = new HashSet<string>();
var result = new List<Room>();
foreach(var room in ListofRooms)
{
if(seenBuildingNames.Add(room.BuildingName))
{
// First time we are encountering this building; add room to result.
result.Add(room);
}
}
Upvotes: 4