无法为Linq查询找到合适的操作符
本文关键字:操作符 Linq 查询 | 更新日期: 2023-09-27 17:51:04
我需要帮助构建Linq查询。我有这本字典:
var dict = new Dictionary<string, IDictionary<int, double>>
{
{ "one", new Dictionary<int, double>
{
{ 1, 2.0 },
{ 2, 3.0 }
}},
{ "two", new Dictionary<int, double>
{
{ 1, 3.0 },
{ 2, 4.0 },
{ 3, 5.0 }
}},
{ "three", new Dictionary<int, double>
{
{ 1, 4.0 },
{ 2, 5.0}
}}
};
我想选择所有关联值为3.0的"string"/"int"元组。对于Foreach循环,它看起来像:
var res = new Dictionary<string, int>();
foreach (var elem in dict.Select (d => new { S = d.Key, I = d.Value }))
{
foreach (var val in elem.I)
{
if (val.Value == 3.0)
{
res.Add(elem.S, val.Key);
}
}
}
我试图用一个Linq查询做同样的事情,但没有成功(我不知道如何将键与子查询的值"连接")。你会怎么做呢?
提前感谢!
你可以这样做:
var result = dict
// flatten to 3-value tuple
.SelectMany(kvp => kvp.Value
.Select(kvp2 => new // anonymous object
{
OuterKey = kvp.Key, // e.g. "one"
InnerKey = kvp2.Key, // e.g. 1
InnerValue = kvp2.Value // e.g. 2.0
})
).Where(o => o.InnerValue == 3.0) // limit to the 3.0 value
.ToDictionary(o => o.OuterKey, o => o.InnerKey)
;
SelectMany将字典的字典扁平化为如下所示的结构:
{ OuterKey = "one", InnerKey = 1, InnerValue = 2.0 },
{ OuterKey = "one", InnerKey = 2, InnerValue = 3.0 },
{ OuterKey = "two", InnerKey = 1, InnerValue = 3.0 },
{ OuterKey = "two", InnerKey = 2, InnerValue = 4.0 },
{ OuterKey = "two", InnerKey = 3, InnerValue = 5.0 },
{ OuterKey = "three", InnerKey = 1, InnerValue = 4.0 },
{ OuterKey = "three", InnerKey = 2, InnerValue = 5.0 }
Where()将其限制为只有InnerValue = 3.0的对象:
{ OuterKey = "one", InnerKey = 2, InnerValue = 3.0 },
{ OuterKey = "two", InnerKey = 1, InnerValue = 3.0 }
ToDictionary()是这样的:
{ "one", 2 },
{ "two", 1 }
如果可能在同一个外键下有多个3.0,那么您可以使用tollookup()而不是ToDictionary()。
这是另一种非常难看的方法:
var results = from key1 in dict.Keys
let valueDict = dict[key1]
from key2 in valueDict.Keys
where valueDict[key2] == 3d
select new { Key1 = key1, Key2 = key2 };
可以这样做:
var res = dict
.Where(outer => outer.Value.Any(inner => inner.Value == 3.0))
.ToDictionary(outer => outer.Key, outer => outer.Value.First(x=>x.Value == 3.0).Key);
或者让代码更通用一点:
var predicate = new Func<KeyValuePair<int, double>, bool>(inner => inner.Value == 3.0);
var res = dict
.Where(outer => outer.Value.Any(inner => predicate(inner)))
.ToDictionary(outer => outer.Key, outer => outer.Value.First(inner => predicate(inner)).Key);