将具有内部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中做到这一点?

将具有内部IEnumerable的结构体的IEnumerable转换为单个字典

您可以使用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 sstring 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);
}