在ArrayList中检查重复项

5
我有一个包含名为Room的项的ArrayList。每个房间都有一个房间类型,例如厨房、接待等。 在将其添加到列表之前,我想检查ArrayList中是否存在该类型的任何房间。 有没有人推荐一种简洁的方法来完成此操作,而不需要多次使用foreach循环?
(.NET 2.0)
我无法访问linq技术,因为我正在运行.net 2.0。我应该在问题中说明这一点。 抱歉。
6个回答

10

在这里我不会使用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>


1
if (!rooms.Any (r => r.RoomType == typeToFind /*kitchen, ...*/))
  //add it or whatever

啊,抱歉我正在运行在 .net 2 上,很不幸。 - anonym0use
@OJ:只有使用LINQBridge才能使用2.0版本...任何.NET 3.5都提供了;您可以使用C# 3.0 lambdas的Exists语法。 - Marc Gravell
啊,"Any"方法逃过了我的注意;)但你不需要使用Any,你可以使用Find,它不需要LINQ。 - OJ.

1

从你的问题中,我并不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);
}

0
另一种方法是对数组进行排序,然后遍历元素,直到找到相邻重复的一对。走到最后,数组就没有重复项了。

0

我曾认为使用列表并进行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只是一个未使用的虚拟变量。


0

不使用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);
   }
}

字典中的值类型实际上并不重要,因为你关注的唯一是键。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接