public Dictionary<string, Dictionary<int, List<int>>> fuBenNPCDictionary;
。。。something;
IEnumerable<(string fuben, int pos)> query = from string fuben in fuBenNPCDictionary.Keys
let fubendict = fuBenNPCDictionary[fuben]
from int pos in fubendict.Keys
where fubendict[pos].Contains(npc.ID)
select (fuben, pos);
if (query.Count() > 0)
foreach ((string fuben, int pos) in query)
{
placestr = "在" + jsonData.instance.SceneNameJsonData[fuben]["MapName"].str.ToCN() + "的第" + pos.ToString() + "位置";
}
这个查询原来是手工foreach,后来VS把它变成了Linq形式,我不是很擅长linq,想把它转换成Linq方法lambda语法。
1条答案
按热度按时间1dkrff031#
简要说明
如果您不熟悉
SelectMany
,那么现在考虑一下这段代码将做什么可能会更容易:首先我们从
fuBenNPCDictionary.Keys
上的一个Select
开始,获取每个字符串键,并将其Map到后续代码的返回值,换句话说,对于dict中的每个键,执行某种计算或过程,然后给予我一个新的列表,其中包含该过程的返回值。在这个
Select
中,我们可以考虑一下我们对其中一个键做了什么,我们将得到这个键对应的值:fuBenNPCDictionary[fuben]
,即现在的Dictionary<int, List<int>>
。我们希望过滤此处的值,使其仅包含相关的List<int>
,因此我们将使用Where
。接下来,我们希望将过滤后的List
和Select
作为元组(fuben, fubenDict.Key)
。注意,我们从当前Select
的直接作用域中获取fubenDict
,但是我们可以从父对象Select
的作用域中获取fuben
,如果我们编写如下语句(为了简洁起见,省略了Where
),就更容易看出这是有效的:综上所述,最后剩下的就是
query2
包含了我们不希望的额外嵌套级别:它的类型是IEnumerable<IEnumerable<(string key, int Key)>>
而不是IEnumerable<(string key, int pos)>
,所以不是一个列表,而是一个列表的列表,答案是把外部的Select
改为SelectMany
,一个简单的SelectMany
的例子是,如果你有一个数组,看起来像您可以执行
SelectMany(x => x)
以获得[1, 2, 1]
,从而将交错数组扁平化为单个数组。