2017-02-22 101 views
0

我有一個簡單的key,value格式的文件,每行一個。 e.g:爲什麼不是這個LINQ正確解析文件?

word1,filepath1 
word2,filepath2 
word3,filepath5 

我想一氣呵成使用LINQ到讀入Dictionary<string,string>這一點。文件中有一些重複項(第一部分 - 第一個字符串 - 是重複項)。在這種情況下,我可以放棄重複項。

這是我的LINQ這是不工作:

var indexes = File.ReadAllLines(indexFileName) 
    .Select(x => x.Split(',')) 
    .GroupBy(x=>x[0]) 
    .ToDictionary(x => x.Key, x => x.ElementAt(1)); 

ToDictionary部分是困惑我,我怎麼從組檢索的第一個值,並將其分配到字典中的價值?

我得到一個System.ArgumentOutOfRangeException: 'Specified argument was out of the range of valid values.'異常。

+2

所以上面的代碼不工作,任何erros? –

+1

這聽起來像是你沒有在期待它。這給了你什麼? – krillgar

+3

*我如何檢索組中的第一個值* - 正確命名的First()方法將成爲我的首選。 –

回答

2
var indexes = File.ReadAllLines(indexFileName) 
        .Select(x => x.Split(',')) 
        .GroupBy(x => x[0]) 
        .ToDictionary(x => x.Key, x => x.First()[1]); 
2

所以這裏的問題是,你是分組數組,而不是字符串。因此,您在ToDictionary() lambda中處理的組對象是枚舉數組,而不是字符串。 g.ElementAt(0)不是一個字符串。這是串的第一陣列:

g.Key == "word1" 

然後g.ElementAt(0)是...

{ "word1", "filepath1" } 

所以你要g.ElementAt(0).ElementAt(1),或g.First()[0],或諸如此類的話。

在事後看來,這似乎很明顯,但不幸的是只有在事後,對我來說。

我建議您在接受Matthew Whited的回答後,通過將分割線儘快轉換爲匿名對象來澄清代碼。 ElementAt(1)通訊不多。

var indexes = 
    File.ReadAllLines(indexFileName) 
    .Where(s => !String.IsNullOrEmpty(s)) 
    .Select(x => x.Split(',')) 
    // Turn the array into something self-documenting 
    .Select(a => new { Word = a[0], Path = a[1] }) 
    .GroupBy(o => o.Word) 
    .ToDictionary(g => g.Key, g => g.First().Path) 
    ; 

將每行轉換爲對象使我更容易思考,並且Intellisense也開始在您的團隊中進行遊戲。

+2

很好地完成。除此之外,首先一個小組是安全的,因爲總會有至少一個成員。 –

+0

@DavidB對,如果沒有至少一個成員,它不會存在嗎?謝謝!並感謝發現那個流浪'x'。 –

相關問題