代码之家  ›  专栏  ›  技术社区  ›  Thorin Oakenshield

C:向字典添加数据

  •  2
  • Thorin Oakenshield  · 技术社区  · 14 年前

    我有一张单子

    List<string> TempList = new List<string> { "[66,X,X]", "[67,X,2]", "[x,x,x]" };
    

    我需要从上面的列表向字典添加数据

    Dictionary<int, int> Dict = new Dictionary<int, int>();
    

    所以听写应该包含

    Key --> 66 value --> 67
    

    我需要从第一个字符串([66,x,x])中获取66(第一个值),从第二个字符串([67,x,x])中获取67(第一个值),并将其作为键值对添加到字典中。

    现在,我按照字符串替换和循环方法来完成这项工作。

    在LINQ或正则表达式中有什么方法可以做到这一点吗?

    5 回复  |  直到 14 年前
        1
  •  1
  •   slugster Joey Cai    14 年前

    下面是一个使用这两种方法的示例 string.Split() 和正则表达式:

    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                List<string> data = new List<string>() { "[66,X,X]", "[67,X,2]", "[x,x,x]" };
                addToDict(data);
    
                Console.ReadKey();
            }
    
            private static void addToDict(List<string> items)
            {
                string key = items[0].Split('[', ',')[1];
                string val = items[1].Split('[', ',')[1];
    
                string pattern = @"(?:^\[)(\d+)";
                Match m = Regex.Match(items[0], pattern);
                key = m.Groups[1].Value;
                m = Regex.Match(items[1], pattern);
                val = m.Groups[1].Value;
    
                _dict.Add(key, val);
            }
    
            static Dictionary<string, string> _dict = new Dictionary<string, string>();
        }
    }
    

    不过,我怀疑您的示例是精心设计的,因此可能有更好的解决方案,特别是当您需要将大量字符串处理成键/值对时(我故意对索引值进行硬编码,因为您的示例非常简单,我不想让答案过于复杂)。如果输入数据在格式上是一致的,那么您可以假设使用固定索引,但是如果可能存在一些差异,那么可能需要更多的代码来检查其有效性。

        2
  •  2
  •   jeroenh    14 年前

    在你评论说你是从一个列表开始后,我理解你在追求什么。我在这里重用Jaroslav的“getnumber”函数。用字符串数组编写了我的示例,但工作方式应该相同。如果您有重复的键,下面的代码将抛出,我认为如果您使用字典,这就是您想要的。

            var input = new []
                            {
                                new [] { "[66,X,X]", "[67,X,2]", "[x,x,x]" },
                                new [] { "[5,X,X]", "[8,X,2]", "[x,x,x]" }
                            };
    
            var query = from l in input
                        select new 
                        {
                         Key = GetNumber(l.ElementAt(0)), 
                         Value = GetNumber(l.ElementAt(1))
                         };
    
            var dictionary = query.ToDictionary(x => x.Key, x => x.Value);
    
        3
  •  1
  •   Mark Cidade    14 年前

    可以使用正则表达式从列表中的每个项中提取值,如果需要,可以使用LINQ选择两个列表并将它们压缩在一起(在C 4.0中):

    var regex      = new Regex(@"\d+");
    var allValues  = TempList.Select(x =>int.Parse(regex.Match(x).Value));
    var dictKeys   = allValues.Where((x,index)=> index % 2 == 0); //even-numbered 
    var dictValues = allValues.Where((x,index)=> index % 2 > 0); //odd numbered 
    var dict       = dictKeys.Zip(dictValues, (key,value) => new{key,value})
                             .ToDictionary(x=>x.key,x=>x.value);
    

    如果您使用的是C 3.5,您可以使用 Eric Lippert's implementation of Zip() .

        4
  •  0
  •   Jaroslav Jandek    14 年前

    如果我理解正确:您希望创建链接节点,如 66 -> 67, 67 -> 68, ... n -> n+1 ?

    我不会使用LINQ:

    private static int GetNumber(string s)
    {
        int endPos = s.IndexOf(',');
        return Int32.Parse(s.Substring(1, endPos-1));
    }
    

    在代码中:

    int first, second;    
    for (int i = 1; i < TempList.Count; i++)
    {
        first = GetNumber(TempList[i - 1]);
        second = GetNumber(TempList[i]);
    
        Dict.Add(first, second);
    }
    

    您还应该执行检查等。
    该示例假定列表至少包含2个项。

        5
  •  0
  •   Amy B    14 年前
    List<List<string>> source = GetSource();
    
    Dictionary<int, int> result = source.ToDictionary(
      tempList => GetNumber(tempList[0]),
      tempList => GetNumber(tempList[1])
    );