3

我有一个 Room 对象列表,每个房间对象都有一个 Building 属性;

 public class Room
{
      public string BuildingName;
      public string Name 
}

我现在想过滤我的收藏,我只从每栋建筑物中取 1 个房间(我不在乎哪一个)

所以例如

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

在这种情况下,我想通过一个函数运行这个列表,该函数将返回一个包含 2 个项目的数组(每个建筑物一个)

4

2 回答 2

4

LINQ 对于此类任务非常方便:

var result = ListofRooms.GroupBy(room => room.BuildingName)
                        .Select(buildingGroup => buildingGroup.First())
                        .ToList();

这样做是为每个建筑物创建一个桶(由建筑物中的房间组成),然后从每个桶中选择一个房间,最后将选定的房间具体化为一个集合。

一些切线点:

  1. 标准 C# 命名约定规定局部变量应以 camelCase ( listOfRooms) 命名,而不是 PascalCase ( ListofRooms)。
  2. 如果您愿意,您可以去掉对象初始化器中无参数构造函数的括号,如下所示:new Room { BuildingName = "Building 1", Name = "Room 1" }

如果您不想为此使用 LINQ,我会这样做:

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);
    }
}
于 2013-03-09T04:52:46.713 回答
0

您可以使用这种方法:

var result = ListofRooms.Distinct(new BuildingEqualityComparer());

课程BuildingEqualityComparer如下:

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

这种方法实际上很少使用,因为您需要实现IEqualityComparer一个 PITA,但这只是实现您需要的另一种方法,所以如果您喜欢它或发现它更简单,请使用它!!!

于 2013-03-09T05:43:03.710 回答