是否有一种简单的方法可以为嵌套字典添加值。我正在寻找一种方法来轻松替换以下类型的代码。
if (NestedDictionary.ContainsKey(key1))
{
if (NestedDictionary[key1].ContainsKey(key2))
{
if (NestedDictionary[key1][key2].ContainsKey(key3))
{
//do nothing
}
else
{
NestedDictionary[key1][key2].Add(key3,1);
}
}
else
{
NestedDictionary[key1].Add(key2, new Dictionary<int,int>() { { key3, 1 } });
}
}
else
{
NestedDictionary.Add(key1, new Dictionary<int, Dictionary<int,int>>() { { key2, new Dictionary<int,int>() { { key3, 1} } } });
}
答案 0 :(得分:5)
我们可以编写一个GetOrAdd
方法,可以获取特定密钥的值(如果有),或者如果没有,则分配一个新值:
public static TValue GetOrAdd<TKey, TValue>(
this Dictionary<TKey, TValue> dictionary,
TKey key,
TValue newValue)
{
TValue oldValue;
if (dictionary.TryGetValue(key, out oldValue))
return oldValue;
else
{
dictionary.Add(key, newValue);
return newValue;
}
}
(注意,您可以创建第二个重载,接受Func<TValue>
而不是TValue
,如果创建的值很昂贵或导致副作用,这很有用。)
现在这个问题变得非常简单了:
var dictionary = new Dictionary<int, Dictionary<int, string>>();
dictionary.GetOrAdd(key1, new Dictionary<int, string>())[key2] = value;
我们获取外键的内部字典,或者如果它不存在则创建一个新的空字典,然后我们将新值分配给返回的字典。请注意,如果项目不存在,索引器将添加项目,如果项目已经存在则更新项目。
当我们添加尺寸时,这当然可以很好地扩展:
var dictionary = new Dictionary<int, Dictionary<int, Dictionary<int, string>>>();
dictionary.GetOrAdd(key1, new Dictionary<int, Dictionary<int, string>>())
.GetOrAdd(key2, new Dictionary<int, string>())[key3] = value;
在我们的情况下,我们实际上总是使用TValue
方法添加默认值GetOrAdd
,所以如果我们添加一个重载来支持:
public static TValue GetOrAdd<TKey, TValue>(
this Dictionary<TKey, TValue> dictionary,
TKey key)
where TValue : new()
{
TValue oldValue;
if (dictionary.TryGetValue(key, out oldValue))
return oldValue;
else
{
var newValue = new TValue();
dictionary.Add(key, newValue);
return newValue;
}
}
它进一步简化了代码:
dictionary.GetOrAdd(key1).GetOrAdd(key2)[key3] = value;
如果你真的最终完成了这个特定的操作 lot ,你可以创建一个方法来完成整个事情:
public static void AddMany<TKey1, TKey2, TKey3, TValue>(
this Dictionary<TKey1, Dictionary<TKey2, Dictionary<TKey3, TValue>>> dictionary,
TKey1 key1,
TKey2 key2,
TKey3 key3,
TValue newValue)
{
dictionary.GetOrAdd(key1).GetOrAdd(key2)[key3] = newValue;
}
允许你写:
dictionary.AddMany(key1, key2, key3, value);
当然,您需要为要支持的每个键创建一个新的AddMany
重载,并且它必须是编译时已知的数字,但在您的情况下确实如此。示例
答案 1 :(得分:0)
您可以简化内部部分:
if (NestedDictionary.ContainsKey(key1))
{
if (NestedDictionary[key1].ContainsKey(key2))
{
NestedDictionary[key1][key2][key3]=1;
}
else
{
NestedDictionary[key1].Add(key2, new Dictionary<int,int>() { { key3, 1 } });
}
}
else
{
NestedDictionary.Add(key1, new Dictionary<int, Dictionary<int,int>>() { { key2, new Dictionary<int,int>() { { key3, 1} } } });
}
但那是关于它的。
但结构有什么意义呢?你只需要在最里面的字典中添加一个常量值(1),所以那里没有真正的“值”。您也可以在该级别使用List<string>
。