C#Linq .ToDictionary()密钥已经存在
最终编辑:我能够找到ini文件中的重复字段。 谢谢大家的帮助!
我正在使用正则表达式来解析ini文件,使用LINQ将其存储在Dictionary中:
样本数据:
[WindowSettings]
窗口X Pos =’0′
窗口Y Pos =’0′
Window Maximized =’false’
窗口名称=’Jabberwocky’[记录]
目录=’C: Rosetta Stone Logs’
编辑:这是实际导致问题的文件: http : //pastebin.com/mQSrkrcP
EDIT2:我把它缩小到由文件的最后一部分引起:[list_first_nonprintable]
由于某种原因,我正在解析的文件之一是抛出此exception:
System.ArgumentException:已添加具有相同键的项。
有没有办法让我找出导致问题的键(所以我可以修复文件),或者只是跳过导致这个问题的键并继续解析?
这是代码:
try { // Read content of ini file. string data = System.IO.File.ReadAllText(project); // Create regular expression to parse ini file. string pattern = @"^((?:[)(?[^]]*)(?:])(?:[rn]{0,}|Z))((?![)(?[^=]*?)(?:=)(?[^rn]*)(?:[rn]{0,4}))*"; //pattern = @" //^ # Beginning of the line //((?:[) # Section Start // (?[^]]*) # Actual Section text into Section Group // (?:]) # Section End then EOL/EOB // (?:[rn]{0,}|Z)) # Match but don't capture the CRLF or EOB // ( # Begin capture groups (Key Value Pairs) // (?![) # Stop capture groups if a [ is found; new section // (?[^=]*?) # Any text before the =, matched few as possible // (?:=) # Get the = now // (?[^rn]*) # Get everything that is not an Line Changes // (?:[rn]{0,4}) # MBDC rn // )* # End Capture groups"; // Parse each file into a Dictionary. Dictionary<string, Dictionary> iniFile = (from Match m in Regex.Matches(data, pattern, RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline) select new { Section = m.Groups["Section"].Value, kvps = (from cpKey in m.Groups["Key"].Captures.Cast().Select((a, i) => new { a.Value, i }) join cpValue in m.Groups["Value"].Captures.Cast().Select((b, i) => new { b.Value, i }) on cpKey.i equals cpValue.i select new KeyValuePair(cpKey.Value, cpValue.Value)).ToDictionary(kvp => kvp.Key, kvp => kvp.Value) }).ToDictionary(itm => itm.Section, itm => itm.kvps); return iniFile; } catch (ArgumentException ex) { System.Diagnostics.Debug.Write(ex.ToString()); return new Dictionary<string, Dictionary>(); }
提前致谢。
这只是意味着当你转换为字典时 –
.ToDictionary(itm => itm.Section, itm => itm.kvps);
– 有多个键(itm.Section)。 您可以使用ToLookup ,它有点像字典但允许多个键。
编辑
有几种方法可以调用ToLookup 。 最简单的是指定键选择器:
var lookup = // ... .ToLookup(itm => itm.Section);
这应该提供一个查找,其中键的类型为Group 。 获取查找值应返回IEnumerable,其中T是匿名类型:
Group g = null; // TODO get group var lookupvalues = lookup[g];
如果.NET编译器不喜欢这个(有时它似乎很难弄清楚各种类型应该是什么),你也可以指定一个元素选择器,例如:
ILookup> lookup = // ... .ToLookup( itm => itm.Section.Value, // key selector itm => itm.kvps // element selector );
您可以编写自己的ToDictionary方法,该方法不会轻易破坏重复键。
public static Dictionary ToDictionary( this IEnumerable source, Func keySelector, Funct valueSelector) { //TODO validate inputs for null arguments. Dictionary output = new Dictionary(); foreach(TSource item in source) { //overwrites previous values output[keySelector(item)] = valueSelector(item); //ignores future duplicates, comment above and //uncomment below to change behavior //K key = keySelector(item); //if(!output.ContainsKey(key)) //{ //output.Add(key, valueSelector(item)); //} } return output; }
我假设你可以弄清楚如何实现额外的重载(没有值选择器)。
您可以使用Tuple
传递多个键。 检查下面的示例代码:
上述就是C#学习教程:C#Linq .ToDictionary()密钥已经存在分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
.ToDictionary(k => new Tuple(k.key1,k.key2), v => v.value)
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1003117.html