将具有内部IEnumerable的结构体的IEnumerable转换为单个字典
本文关键字:IEnumerable 单个 字典 转换 结构体 内部 | 更新日期: 2023-09-27 18:06:48
I和IEnumerable<MyStruct>
和MyStruct
看起来如下:
struct MyStruct
{
public IEnumerable<string> aliases;
public Action action;
public MyStruct(IEnumerable<string> aliases, Action action)
{
this.aliases = aliases;
this.action = action;
}
}
我想把它变成一个字典,其中键将是aliases
中的每个字符串,值将是action
。例如,如果我在IEnumerable
中有两个MyStruct
对象,第一个有别名"o", "on", "one"
和动作a1
,第二个有别名"t", "tw", "two"
和动作a2
,我希望结果字典看起来像这样:
{"o", a1},
{"on", a1},
{"one", a1},
{"t", a2},
{"tw", a2},
{"two", a2}
我想知道是否有任何方法在Linq中做到这一点?
您可以使用SelectMany
来平化别名列表,并创建一个包含别名和操作的临时匿名类型。最后将这个列表转换为ToDictionary
:
IEnumerable<MyStruct> source = ...
Dictionary<string, Action> result =
source.SelectMany(s => s.aliases, (s, alias) => new { Alias = alias, s.action })
.ToDictionary(x => x.Alias, x => x.action);
SelectMany
的第一个参数告诉它选择aliases
,因此为MyStruct
的每个MyStruct s
和string alias
调用第二个lambda,并从这两个值中创建一个实例。
最后这个序列被转换成一个字典,使用alias
作为键,action
作为值。
注意,如果别名不是唯一的,这会引发一个ArgumentException
,因为您不能两次向字典添加相同的键。
Linq语法将数据平面化,然后在此基础上使用ToDictionary。
您也可以使用"SelectMany"来平整化数据。
private Dictionary<string, action> FlattenedStructs(IEnumerable<MyStruct> structs)
{
var flattenedItems = from s in structs
from a in s.aliases
select new {Alias = a, Action = s.action};
return flattenedItems.ToDictionary(f => k.Alias, f => f.Action);
}