[英]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.