我目前正在打印特定键的值,如下所示:
var myValue = dic1.FirstOrDefault(x => x.Key == "John").Value;
Console.WriteLine("John in dictionary: " + myValue);
值是约翰在这本词典中多少次的数字。现在我想为整本字典这样做。有任何想法吗?我想过要做到这样:
var dic1Dic2 = dic1.Zip(dic2, (d, z) => new { Dic1= d, Dic2 = z });
foreach (var dz in dic1Dic2)
{
Console.WriteLine(dz.Dic1);
Console.WriteLine(dz.Dic2);
}
但在这种情况下,问题是如果其中一个列表较小,我就不会得到值。地狱,如果一个人得到100个字而且没有,如果没有打印。
我想计算就像在dic1中我说得到键=四和值= 4,在dic2中我得到四和值= 2(例如,它也可能是4,无关紧要),而我想要倍增它们,或分裂或其他什么。在最基本的第一个代码示例中,当我只使用特定键值时,我这样做:
var divideJohn = (myValue1 / myValue);
和myValue1来自:
var myValue1 = dic2.FirstOrDefault(x => x.Key == "John").Value;
那么任何想法如何从字典中的所有内容中获取这些值?
@edit 是的,澄清一下,我有很多词典,我希望他们每个人的价值都能得到一些数学。对于一个制作foreach循环的字典就足够了:
foreach (string item in dic1.Keys)
{
var dif = dic1.FirstOrDefault(x => x.Key == item).Value;
}
但重点是从不同的词典中获取它们并能够在数学中使用它们。
答案 0 :(得分:0)
不幸的是,你的问题并不是很清楚你想要做什么。您的问题陈述中遗漏了许多细节,这些细节将明确指出所需的实际行为。
那就是说,听起来你正在尝试合并你的词典。一个非常简单的版本可能是:
Dictionary<string, int> MergeSum(
Dictionary<string, int> dict1, Dictionary<string, int> dict2)
{
Dictionary<string, int> merged = new Dictionary<string, int>(dict1.Count);
foreach (var kvp in dict1)
{
merged.Add(kvp.Key, kvp.Value + dict2[kvp.Key]);
}
}
请注意,上面隐含的假设是两个词典都包含完全相同的键。不做出这种假设的替代方案可能如下所示:
Dictionary<string, int> MergeSum(
Dictionary<string, int> dict1, Dictionary<string, int> dict2)
{
Dictionary<string, int> merged = new Dictionary<string, int>(dict1.Count);
foreach (var kvp in dict1)
{
int value;
dict2.TryGetValue(kvp.Key, out value);
merged.Add(kvp.Key, kvp.Value + value);
}
foreach (var kvp in dict2)
{
int value;
if (!dict1.TryGetValue(kvp.Key, out value))
{
merged.Add(kvp.Key, kvp.Value);
}
}
}
此处,value
如果在调用TryGetValue()
时字典中不存在,则会设置为0.
在您的问题中,您似乎表明您可能有两个以上的词典要合并。在这种情况下,您可以将字典数组(或其他集合...数组作为输入作为输入,仅用于说明目的):
Dictionary<string, int> MergeSum(Dictionary<string, int>[] dictionaries)
{
Dictionary<string, int> merged = new Dictionary<string, int>();
foreach (Dictionary<string, int> dict in dictionaries)
{
foreach (var kvp in dict)
{
int value;
merged.TryGetValue(kvp.Key, out value);
merged[kvp.Key] = kvp.Value + value;
}
}
}
您可能希望以通用方式执行上述任何操作。这可能看起来像这样:
Dictionary<string, int> Merge(
Dictionary<string, int>[] dictionaries, Func<int, int, int> mergeFunction)
{
Dictionary<string, int> merged = new Dictionary<string, int>();
foreach (Dictionary<string, int> dict in dictionaries)
{
foreach (var kvp in dict)
{
int value;
merged.TryGetValue(kvp.Key, out value);
merged[kvp.Key] = mergeFunction(value, kvp.Value);
}
}
}
您可以这样调用上面的内容:
result = Merge(dictionaries, (i1, i2) => i1 + i2);
有些操作比其他操作更有问题。例如,如果您正在使用乘法,那么由于代码总是从空的初始字典聚合,因此聚合操作结果将始终为0.您可以通过特殊包装第一个字典来解决此问题:
Dictionary<string, int> Merge(
Dictionary<string, int>[] dictionaries, Func<int, int, int> mergeFunction)
{
Dictionary<string, int> merged = new Dictionary<string, int>(dictionaries.First());
foreach (Dictionary<string, int> dict in dictionaries.Skip(1))
{
foreach (var kvp in dict)
{
int value;
merged.TryGetValue(kvp.Key, out value);
merged[kvp.Key] = mergeFunction(value, kvp.Value);
}
}
}
这将使用集合中的第一个字典初始化merged
字典,然后在执行实际聚合循环时跳过该字典。但请注意,即使在那里,在处理每个字典中不存在的键时也存在潜在的问题(例如,如果相乘,如果任何字典缺少该键,则在最终结果中将得到0)。当然,也许这就是你真正想要的。
另请注意,上述所有内容均假设您的值为int
。但是大多数代码都没有真正的假设。只要你有一些组合一对值的有效方法,你就可以轻松地修改上面的代码来做任何你想做的事情。这包括最终示例的完全通用版本:
Dictionary<TKey, TValue> Merge<TKey, TValue>(
Dictionary<TKey, TValue>[] dictionaries, Func<TValue, TValue, TValue> mergeFunction)
{
Dictionary<TKey, TValue> merged = new Dictionary<TKey, TValue>(dictionaries.First());
foreach (Dictionary<TKey, TValue> dict in dictionaries.Skip(1))
{
foreach (var kvp in dict)
{
TValue value;
merged.TryGetValue(kvp.Key, out value);
merged[kvp.Key] = mergeFunction(kvp.Value, value);
}
}
}
(免责声明:上述代码均未编译。我提前为任何印刷错误道歉,并假设找出我真正的意思并不会太难:))。
最后,请注意Enumerable.ToDictionary()
method。我已经编写了上面的一般逻辑,但您可能会发现可以使用各种LINQ操作(包括ToDictionary()
方法)来简化代码并使其更能表达您的实际意图(即代码显示更多你想做什么,而不是 如何完成。