我有一本字典但是有很多实例可以添加重复数据。我试图阻止添加重复键或值。但是,使用此代码我仍然可以获得"已经添加了具有相同密钥的项目"。我想只在词典中添加新的键和值,如果它们尚未添加到词典中。
for (var i = 0; i < nodes.Count; ++i)
{
if (!webidsAndXPaths.ContainsKey(nodes[i].Id) || !webidsAndXPaths.ContainsValue(nodes[i].XPath)) // if the key or value does not exist then add it to the dictionary
webidsAndXPaths.Add(nodes[i].Id, nodes[i].XPath); // now we put the data in a dictionary <key = id, value = xpath>
}
答案 0 :(得分:4)
因为如果您遇到具有相同键但具有不同值的项目,那么它仍会尝试插入它。如果确实想要阻止重复值,那么您需要使用&&
代替:
if (!webidsAndXPaths.ContainsKey(nodes[i].Id) &&
!webidsAndXPaths.ContainsValue(nodes[i].XPath)) // if the key AND value do not exist then add it to the dictionary
但是防止重复的值对于字典来说似乎是一个奇怪的要求。 Dictionary
仅要求Key
是唯一的 - 重复Value
没有问题。也许你只想要唯一的键/值对?
如果重复的键是唯一关注的问题,那么这将是一个正确的方法:
if (!webidsAndXPaths.ContainsKey(nodes[i].Id)) // if the key does not exist then add it to the dictionary
另一种选择是设置值,无论它是否存在。唯一的区别是找到的 last 值将“赢”而不是 first :
for (var i = 0; i < nodes.Count; ++i)
{
webidsAndXPaths[nodes[i].Id] = nodes[i].XPath;
}
如果密钥存在,使用索引器([]
)不会抛出异常,但会覆盖该密钥的值(或者如果密钥不存在)
答案 1 :(得分:3)
您正在使用||
,这意味着如果您的字典中的值不存在,那么即使已经添加了密钥,该语句也会评估为 true 。将if语句分开或使用 AND (&&
)而不是OR
。
if (!webidsAndXPaths.ContainsKey(nodes[i].Id) &&
!webidsAndXPaths.ContainsValue(nodes[i].XPath))
{
webidsAndXPaths.Add(nodes[i].Id, nodes[i].XPath);
}
答案 2 :(得分:2)
仅检查密钥,而不是值。因为ContainsValue
可能会返回false
,但已经添加了相同的密钥,在这种情况下,您将获得异常。
if (!webidsAndXPaths.ContainsKey(nodes[i].Id))
webidsAndXPaths.Add(nodes[i].Id, nodes[i].XPath);
如果您需要键和值是唯一的,您可以创建自定义不可变结构,其中包含两个属性(Id,Xpath),然后将其添加为键。
UPDATE1:
您似乎只是担心异常,值得注意的是,重复值不会抛出异常,但重复的密钥会出现。
如果您获得重复密钥,如果您决定使用最新到达的值,则可以执行以下操作。
webidsAndXPaths[nodes[i].Id] = nodes[i].XPath;
这不会抛出异常,如果已经存在相同的密钥,它将覆盖该值。
答案 3 :(得分:1)
如果你真正需要的是唯一键值对,我想你想在这里使用Tuple
。你可能有这样的事情:
var kvpList = new List<Tuple<string, string>>();
然后你可以这样做:
var newTuple = Tuple.Create(nodes[i].Id, nodes[i].XPath);
if (!kvpList.Contains(newTuple))
kvpList.Add(newTuple);
这是有效的,因为元组的默认比较是按值计算的。