我怎么能合并两个字典没有得到关键的ArgumentException ?



当我尝试合并两个字典时,我不知道如何在字典上保留键和值。由于密钥的重复,我一直得到ArgumentException。当键匹配时,我只想通过=+ kvp.value;

添加值我有一个字典列表

第一字典=kvp = "jump", 2;

2ndDictionary =kvp = "jump", 4;

我喜欢合并它们,得到这样的东西:字典=kvp = "jump", 6;

我可以稍后添加到我的字典列表

我试图运行一些我在StackOverflow线程中发现的东西。

foreach (var dict in listOfDict)
{
dict.SelectMany(d => d)
.ToLookup(pair => pair.Key, pair => pair.Value)
.ToDictionary(group => group.Key, group => group.First());
}

但我一直在。

不能从用法中推断出来。尝试指定类型参数明确。

我想避免在单独的列表中获取所有的键和值,然后在新字典中循环添加键和值。

使用Linq:

对双精度值字典列表进行最简单的扩展
public static class ExtListOfDict {
public static Dictionary<TKey, double> SumValue1<TKey>(this List<Dictionary<TKey, double>> list)        
=> list?.SelectMany(i => i).ToLookup(i => i.Key, i => i.Value).ToDictionary(i => i.Key, i => i.Sum());
}

没有linq:

public static Dictionary<TKey, double> SumValue2<TKey>(this List<Dictionary<TKey, double>> list) {
if(list?.Count > 0) {
var dir = new Dictionary<TKey, double>(list[0]);
for(var i = 1; i < list.Count; i++) 
foreach (var kv in list[i])
if (dir.TryGetValue(kv.Key, out double sum))
dir[kv.Key] = sum + kv.Value; 
else 
dir.Add(kv.Key, kv.Value);                    
return dir;
} else
return null;
}

如果你喜欢LINQ方法,我会这样做:

var dictionaries = new List<Dictionary<string, int>>(); // this is the list of dictionaries you want to merge
var unifiedDictionary = new Dictionary<string, int>(); // this is the dictionary where you merge and add the values
foreach (var kvp in dictionaries.SelectMany(dictionary => dictionary))
{
if (unifiedDictionary.ContainsKey(kvp.Key))
{
unifiedDictionary[kvp.Key] += kvp.Value;
}
else
{
unifiedDictionary.Add(kvp.Key, kvp.Value);
}
}

但是,如果这太难阅读(我并不总是喜欢过多的LINQ而不是显式代码块),您可以使用for-loop方法:

var dictionaries = new List<Dictionary<string, int>>(); // this is the list of dictionaries you want to merge
var unifiedDictionary = new Dictionary<string, int>(); // this is the dictionary where you merge and add the values
foreach (var dictionary in dictionaries)
{
foreach (var kvp in dictionary)
{
if (unifiedDictionary.ContainsKey(kvp.Key))
{
unifiedDictionary[kvp.Key] += kvp.Value;
}
else
{
unifiedDictionary.Add(kvp.Key, kvp.Value);
}
}
}

希望这对你有帮助。如果需要进一步的帮助和解释,请告诉我。

下面是一个基于CollectionsMarshal.GetValueRefOrAddDefaultAPI的解决方案。. NET 6),并在INumber<TSelf>接口(。净7):

public static Dictionary<TKey, TValue> ToSumDictionary<TKey, TValue>(
this IEnumerable<Dictionary<TKey, TValue>> dictionaries)
where TValue : struct, INumber<TValue>
{
ArgumentNullException.ThrowIfNull(dictionaries);
Dictionary<TKey, TValue> result = null;
foreach (var dictionary in dictionaries)
{
if (result is null)
{
result = new(dictionary, dictionary.Comparer);
continue;
}
if (!ReferenceEquals(dictionary.Comparer, result.Comparer))
throw new InvalidOperationException("Incompatible comparers.");
foreach (var (key, value) in dictionary)
{
ref TValue refValue = ref CollectionsMarshal
.GetValueRefOrAddDefault(result, key, out bool exists);
refValue = exists ? refValue + value : value;
}
}
result ??= new();
return result;
}

每个字典中每个KeyValuePair<TKey, TValue>的键只被散列一次。

如果你得到一个异常,由于重复的密钥,那么听起来你有重复的密钥!

在合并这两本字典之前,你检查过了吗?简单地调用=+ kvp.value而不检查第一个字典是否已经有该名称的键,这很可能是您的问题。

您需要检查具有该键的现有条目,如果找到了,则采取适合您的场景的任何操作(例如忽略,覆盖,要求用户决定等)

相关内容

  • 没有找到相关文章

最新更新