假设您正在传递具有相同键和相同值的 KeyValuePair,这是使用 ObseravableCollection 可能最有效的方式。
public void DeleteGroup2(KeyValuePair<int, string> group)
{
Groups.Remove(group);
}
之所以有效,是因为 KeyValuePair 是一个结构,当应用重载运算符 == 时,它会比较结构的 Key 和 Value 数据成员。
同样,如果您传入 Groups obserabableCollection 中包含的完全相同的键和值,这将正常工作...如果值不匹配,它将无法正常工作。
在幕后,ObserableCollection 几乎是一个列表,因此它必须遍历执行 == 运算符的每个项目。您发布的代码也是如此。仅仅因为它使用 LINQ 并不意味着它更有效。它不像 LINQ where 子句使用任何索引,就像使用 LINQ to SQL 一样。
public void DeleteGroup3(KeyValuePair<int, string> groupToDelete)
{
var itemsToDelete =
(
from g in Groups
where g.Key == groupToDelete.Key
select g
);
foreach (var kv in itemsToDelete)
{
Groups.Remove(kv);
}
}
如果您想保证删除所有项目,即使是具有重复键的项目,这可能是使用 linq 最有效的方法。
public void DeleteGroup4(KeyValuePair<int, string> group)
{
List<int> keyIndexes = new List<int>();
int maxIndex = Groups.Count;
for (int i = 0; i < maxIndex; i++)
{
if (Groups[i].Key == group.Key)
{
keyIndexes.Add(i);
}
}
int indexOffset = 0;
foreach (int index in keyIndexes)
{
Groups.RemoveAt(index - indexOffset);
indexOffset++;
}
}
如果您有多个具有相同键的项目,或者您不知道与原始键完全相同的键值对,这应该是所有项目中性能最好的。
我相信您的 DeleteGroup 方法对于外部 Any while 循环是 2N^2...N 的 BIG O,对于第一个循环是 N,对于删除是 N。将外部循环乘以内部的总和,得到 2N^2
DeleteGroup2 是 N 中的 BIG O,并且在所有这些中具有最佳性能。缺点是您需要知道 Key 和 Value 而不仅仅是 Key。它也只会删除它找到的第一个项目。它不会删除具有相同 Key 和相同 Value 的重复项。
删除组 3 是 N + N^2 的大 O。 N 为选择。更糟糕的情况是您的密钥在那里 N 次,因此 N^2 用于删除。
DeleteGroup4 是 2N 的 BIG O。 N 来查找索引,在最坏的情况下,如果所有项目都具有相同的键,那么它的 N 删除它们中的每一个,因为 RemoveAtIndex 是 1 的大 O。如果你只知道键并且你有可能有多个项目具有相同的 Key。
如果您知道您不会有重复的项目,我会使用 DeleteGroup2。如果您有重复的可能性,DeleteGroup4 应该具有最佳性能。
附带说明,如果没有重复项并且您不一定知道 Key 和 Value,您仍然可以使用 DeleteGroup2 的最佳性能选项,但创建一个名为 KeyValueIntString 的类,该类具有 Key 和 Value 的属性。然后覆盖 IsEquals 方法,使其仅比较 Key 属性,这与比较 Key 和 Value 数据成员的 KeyValue 结构不同。然后您可以使用 ObserableCollection.Remove 方法,而不必担心知道存储的值。 IE。您可以传入设置了 Key 的 KeyValueIntString 实例,但您不必担心设置 Value 属性。
评论后我决定添加最佳可读性方法,尽管它的性能确实更差。有一个 N^4 的大 O。 N 代表 select,N 代表 ToList,N 代表 ForEach,N 代表 Remove。
public void DeleteGroup5(KeyValuePair<int, string> groupToDelete)
{
(
from g in Groups
where g.Key == groupToDelete.Key
select g
).ToList().ForEach(g => Groups.Remove(g));
}