我有一个包含名为Room的项的ArrayList。每个房间都有一个房间类型,例如厨房、接待等。
在将其添加到列表之前,我想检查ArrayList中是否存在该类型的任何房间。
有没有人推荐一种简洁的方法来完成此操作,而不需要多次使用foreach循环?
(.NET 2.0)
我无法访问linq技术,因为我正在运行.net 2.0。我应该在问题中说明这一点。 抱歉。
(.NET 2.0)
我无法访问linq技术,因为我正在运行.net 2.0。我应该在问题中说明这一点。 抱歉。
在这里我不会使用ArrayList
,因为你有.NET 2.0,使用List<T>
将使一切变得简单:
List<Room> rooms = ...
string roomType = "lounge";
bool exists = rooms.Exists(delegate(Room room) { return room.Type == roomType; });
或使用 C# 3.0(仍针对 .NET 2.0)
bool exists = rooms.Exists(room => room.Type == roomType);
使用C# 3.0和LINQBridge或.NET 3.5:
bool exists = rooms.Any(room => room.Type == roomType);
(Any
的使用方式适用于更多类型,而不仅仅是 List<T>
)
if (!rooms.Any (r => r.RoomType == typeToFind /*kitchen, ...*/))
//add it or whatever
从你的问题中,我并不100%确定你是否想要强制规定一个特定类型的房间只能有一个,还是仅仅想知道一下。
如果你有这样一个不变量:任何一组Room
都不能拥有相同的Room
类型,那么你可以尝试使用一个Dictionary<Type, Room>
。
这样做的好处在于,在添加时不会执行线性搜索。
你可以使用以下操作来添加一个房间:
if(rooms.ContainsKey(room.GetType()))
{
// Can't add a second room of the same type
...
}
else
{
rooms.Add(room.GetType(), room);
}
我曾认为使用列表并进行Exists操作需要 O(n)
的时间。相反,使用Dictionary
仅需O(1)
的时间,如果内存不是问题,它更受欢迎。
如果您不需要顺序列表,我建议尝试使用像这样的Dictionary
:
Dictionary<Type, List<Room>> rooms = new Dictionary<Type, List<Room>>;
void Main(){
KitchenRoom kr = new KitchenRoom();
DummyRoom dr = new DummyRoom();
RoomType1 rt1 = new RoomType1();
...
AddRoom(kr);
AddRoom(dr);
AddRoom(rt1);
...
}
void AddRoom(Room r){
Type roomtype = r.GetType();
if(!rooms.ContainsKey(roomtype){ //If the type is new, then add it with an empty list
rooms.Add(roomtype, new List<Room>);
}
//And of course add the room.
rooms[roomtype].Add(r);
}
你基本上有一个不同房间类型的列表。但是如果你不需要ArrayList,这个解决方案就只是可以接受的。但对于大型列表来说,这将是最快的。
我曾经有一个解决方案,使用了300,000多个项目的List<string>。将每个元素与另一个几乎相同大小的列表进行比较需要12小时。将逻辑切换为使用Dictionary后,时间缩短到了12分钟。对于更大的列表,我总是使用Dictionary<mytype, bool>
,其中bool只是一个未使用的虚拟变量。
不使用lambda表达式:
void AddRoom(Room r, IList<Room> rooms, IDictionary<string, bool> roomTypes)
{
if (!roomTypes.Contains(r.RoomType))
{
rooms.Add(r);
roomTypes.Add(r.RoomType, true);
}
}
字典中的值类型实际上并不重要,因为你关注的唯一是键。