使用LINQ解析内部双字典
本文关键字:字典 内部 LINQ 使用 | 更新日期: 2023-09-27 18:21:34
我有一个Dictionary<double, Dictionary<double,double>>
,其中内部字典的键是相同的,我想解析它,以便输出为:
key1,dict1val1,dict2val1
key2,dict1val2,dict2val2
...
对不起,我应该说不需要外钥匙。
下面是我追求的一个例子:
(1.0, (1.0, 1.1)),(2.0, (1.0,1.2))
(1.0, (1.1, 1.3)),(2.0, (1.1,1.4))
(1.0, (1.2, 1.5)),(2.0, (1.2,1.6))
应输出:
1.0,1.1,1.2
1.1,1.3,1.4
1.2,1.5,1.6
在LINQ中有一种优雅的方法可以做到这一点吗?我在字符串词典中看到过类似的问题,但语法不适用于doubles。
我也订了一本关于这个主题的书,但我需要尽快完成。
您可以使用SelectMany
来扩展这些类型的结构:
var expanded = dictionary.SelectMany(outer =>
outer.Value.Select(inner => new {
OuterKey = outer.Key,
InnerKey = inner.Key,
Value =inner.Value
})
);
现在你可以做:
foreach (var item in expanded)
{
Console.WriteLine("{0},{1},{2}", item.OuterKey, item.InnerKey, item.Value);
}
之后,如果你想提取内部键/值的组合,你可以做:
var byInnerKey = expanded.ToLookup(item=> item.InnerKey, item => item.Value)
使用之类的东西打印起来真的很容易
foreach (var item in byInnerKey)
{
string values = string.Join(", ",item);
Console.WriteLine(item.Key + ", " + values);
}
(实例)
注意:这使用了仅在.net4及更高版本中可用的string.Join
方法的重载。
对于.net 3.5及以下版本,您可以使用string
/StringBuilder
循环这些值,也可以将它们强制转换为显式的字符串数组
string values = string.Join(", ",item.Select(d => d.ToString()).ToArray());
(实例3.5)
var d1 = new Dictionary<double, double> { { 1.0, 1.1 } };
var d2 = new Dictionary<double, double> { { 1.0, 1.2 } };
var d3 = new Dictionary<double, double> { { 1.1, 1.3 } };
var d4 = new Dictionary<double, double> { { 1.1, 1.4 } };
var dict1 = new Dictionary<double, Dictionary<double, double>> { { 1.0, d1 }, { 2.0, d3 } };
var dict2 = new Dictionary<double, Dictionary<double, double>>() { { 3.0, d2 }, { 4.0, d4 } };
var keys = dict1.Values.SelectMany(dict => dict.Keys.ToList());
var collection = keys.Select(key1 => new
{
Key = key1,
Values = keys.SelectMany(key =>
dict1.Values.Where(k1 => k1.ContainsKey(key1)).Select(k1 => k1[key1]).Union(
dict2.Values.Where(k2 => k2.ContainsKey(key1)).Select(k2 => k2[key1]))
).Distinct().ToList()
}).ToList();
foreach (var x in collection)
{
Console.Write(x.Key + ": ");
foreach (var y in x.Values)
{
Console.Write(y + ",");
}
Console.WriteLine();
}
这个问题有些奇怪。。这没有道理。。如果使用Dictionary<double, Dictionary<double,double>>
那么就会有一个key1,innedictkey,innedidictvalue
但你指的是一句格言val1?这是它自己的内部字典。。
在任何情况下,你都可以像这个一样循环浏览字典
foreach(var kv in outerdic){
Console.WriteLine(kv.Key + ',' + kv.Value); // kv.Value would be a Dictionary<double, double>
Console.WriteLine(kv.Value[kv.Key]); // this would print the inner value of inner dictionary
}
如果我理解它,结构看起来是这样的:
dict[1.0] ==> dictionary [1.0] ==> 1.1
[1.1] ==> 1.3
[1.2] ==> 1.5
dict[2.0] ==> dictionary [1.0] ==> 1.2
[1.1] ==> 1.4
[1.2] ==> 1.6
然后我们只需遍历第一个字典,并将其与第二个字典进行匹配。
var dict2 = dict[2.0];
var lstResults = dict[1.0].Select(kvp=> String.Format("{0},{1},{2}",
kvp.Key, kvp.Value, dict2[kvp.Key])
.ToList();