繁体   English   中英

将字符串集合转换为字典

[英]Converting Collection of Strings to Dictionary

这可能是一个简单的问题,但答案使我难以理解。

我有一组要转换为字典的字符串。

集合中的每个字符串都是我从正则表达式匹配项中获取的逗号分隔值列表。 我希望字典中每个条目的键是逗号分隔列表中的第四个元素,而对应的值是逗号分隔列表中的第二个元素。

当我尝试直接调用ToDictionary时,最终陷入某种循环,似乎让我踢入了我所在的BackgroundWorker线程:

var MoveFromItems = matches.Cast<Match>()
                           .SelectMany(m => m.Groups["args"].Captures
                           .Cast<Capture>().Select(c => c.Value));

var dictionary1 = MoveFromItems.ToDictionary(s => s.Split(',')[3], 
                                             s => s.Split(',')[1]);

当我手动创建字典时,一切正常:

var MoveFroms = new Dictionary<string, string>();

foreach(string sItem in MoveFromItems) 
{
    string sKey = sItem.Split(',')[3]; 
    string sVal = sItem.Split(',')[1];

    if(!MoveFroms.ContainsKey(sKey))
        MoveFroms[sKey.ToUpper()] = sVal;
}

感谢您提供的任何帮助。

问题很可能是密钥重复。 您有三个选择。

保持第一次输入 (这是您当前在foreach循环中所做的事情)

键只有一个条目,第一个出现-表示您可以拥有一个Dictionary

var first = MoveFromItems.Select(x => x.Split(','))
                         .GroupBy(x => x[3])
                         .ToDictionary(x => x.Key, x => x.First()[1]);

将所有条目分组

键将具有多个条目(每个键返回Enumerable ),并且您使用Lookup而不是Dictionary

var lookup = MoveFromItems.Select(x => x.Split(','))
                          .ToLookup(x => x[3], x => x[1]);

保留所有条目,拼合

没有键之类的东西,只是条目的扁平列表:

var flat = MoveFromItems.Select(x => x.Split(','))
                        .Select(x => new KeyValuePair<string,string>(x[3], x[1]));

您也可以在这里使用元组( Tuple.Create(x[3], x[1]); )。


注意:在这些情况下,您需要确定在什么位置/是否希望按键是大写或小写。 我还没有做任何与此相关的事情。 如果要将键存储为上位键,只需将以上所有内容中的x[3]更改为x[3].ToUpper()

这将Split每个字符串MoveFromItems','和他们进行第四项目(第三指数)为重点和第2项(第一指数)作为价值。

var dict = MoveFromItems.Select(x => x.Split(','))
                         .ToLookup(x => x[3], x => x[1]);

这将拆分每个项目,并从第4个拆分值中选择键,并从第2个拆分值中选择值,所有这些都将成为字典。

var dictionary = MoveFromItems.Select(s => s.Split(','))
                              .ToDictionary(split => split[3],
                                            split => split[1]);

只使用不同的索引将字符串拆分两次是没有意义的。

这就像将拆分结果保存到局部变量中,然后使用它来访问索引3和1一样。

但是,如果您确实不知道密钥是否会再次出现,那么毫无疑问,我将进行您已实现的简单循环。

尽管您的循环中有一个小错误:

MoveFroms = new Dictionary<string, string>();

foreach(string sItem in MoveFromItems) 
{
    string sKey = sItem.Split(',')[3]; 
    string sVal = sItem.Split(',')[1];

    // sKey might not exist as a key
    if (!MoveFroms.ContainsKey(sKey))
    //if (!MoveFroms.ContainsKey(sKey.ToUpper()))
    {
        // but sKey.ToUpper() might exist!
        MoveFroms[sKey.ToUpper()] = sVal;     
    }
}

如果您确实希望键全部使用大写ContainsKey(sKey.ToUpper()) ,则也应在您的条件下执行ContainsKey(sKey.ToUpper())

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM