将字符串集合转换为字典

本文关键字:字典 转换 集合 字符串 | 更新日期: 2023-09-27 18:34:20

这可能是一个简单的问题,但答案是我无法回答的。

有一个字符串集合,我正在尝试将其转换为字典。

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

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

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()即可。

这会拆分每个项目,并从第 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())

这将Split每个字符串与',' MoveFromItems,并从中将第 4 项(第 3 项索引)作为键,将第 2 项(第 1 项)作为值。

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