2014-01-08 54 views
0

我有一個功能:如何使用LINQ包含具有相同密鑰的項目的字典?

private static Dictionary<string, object> FromCookies(HttpCookieCollection cc) 
{ 
return (from string cookie in cc.AllKeys select new { Name = cookie, Value = (object)cc[cookie] }).ToDictionary(kvp => kvp.Name, kvp => kvp.Value, StringComparer.InvariantCultureIgnoreCase); 
} 

但是當我建立,編譯說我:

System.ArgumentException: An item with the same key has already been added. 

但我需要重寫這個項目。我如何使用LINQ來做到這一點?我很抱歉我的愚蠢問題,如果它很容易回答。

+4

您可以先清楚指定兩個cookie具有相同名稱時要執行的操作。 – Jon

+0

@Jon確切地說,這並不像拔出所有非重複鍵那麼簡單。 – James

+0

@LewsTherin我在Visual Studio 2010 Ultimate工作 – matterai

回答

0

您可以隨時使用KeyValuePairs的IEnumerable,這將允許具有相同鍵的多個項目。您不會丟失任何數據:

private static IEnumerable<KeyValuePair<string, object>> FromCookies(HttpCookieCollection cc) 
     { 
      return (from string cookie in cc.AllKeys select new KeyValuePair<string,object>(cookie, cc[cookie])); 
     } 
+0

我已經完成了。但我用foreach。如果字典包含等於KeyValuePair,我檢查每個循環。所以如果它包含的話,我把它換成新的。 – matterai

+0

公平的,如果你只是想處置重複:-)值得記住,雖然該字典實際上實現IEnumerable >,所以字典是更具限制性。您可能還想查看一下Lookup:[link](http://msdn.microsoft.com/zh-cn/library/bb460184(v = vs.110).aspx)如果您想修改一個緩存副本雖然... – AHowgego

0

您可以選擇截然不同的 Cookie以避免重複的字典鍵。但是,當然,結果字典中只有一個值。即如果您有像"Hello""hello""HELLO"這樣的餅乾 - 如果您使用忽略大小寫比較,則無法放置所有這些鍵。下面溶液只選擇第一它們與忽略的情況下(即,只"Hello"密鑰將在這種情況下添加)相等的值的:

return (from string cookie in cc.AllKeys.Distinct(StringComparer.InvariantCultureIgnoreCase) // here 
     select new { 
      Name = cookie, 
      Value = (object)cc[cookie] 
     }) 
     .ToDictionary(kvp => kvp.Name, kvp => kvp.Value); 

BTW代碼可以被簡化爲

return cc.AllKeys // use .Cast<string>() if need 
     .Distinct(StringComparer.InvariantCultureIgnoreCase) 
     .ToDictionary(cookie => cookie, 
         cookie => (object)cc[cookie]); 

因此你會避免匿名對象創建。

+0

這是如何工作的?使用相同鍵和不同值的cookie會發生什麼?我處於低調的邊緣,因爲這可能會或可能不會像OP所希望的那樣工作,但它顯然仍然存在問題,但沒有嘗試澄清。 – Jon

+0

有一個不變的情況下使用。這不起作用。 – Bas

+0

@Jon OP通過'cc [cookie]檢索值,所以值也會相同 –

1

我可能會犯錯,但我不認爲你可以使用LINQ來做到這一點。 return語句創建一個新的字典,它將根據cookie集合中的對象創建。如果此集合包含具有相同名稱的多個對象,則表示存在問題。

我認爲實現這一目標的最佳途徑是通過cookie收集迭代,手動創建字典對象,只是通過使用索引語法設置它們在詞典:

dictionary[cookiename] = cookieValue; 

乾杯!

亞歷

+0

這可以使用LINQ來完成,OP只需要更具體地說明他們想要發生的情況,如果有重複的話。 – James

+0

「但我需要重寫這個項目。」 - >聽起來像OP想要替換前一個對象。 – Alex

0

也許你有重名,就可以使用GroupBy與第一相同StringComparer

private static Dictionary<string, object> FromCookies(HttpCookieCollection cc) 
{ 
    var result = cc.AllKeys 
     .Select(cookie => new { Name = cookie, Value = (object)cc[cookie] }) 
     .GroupBy(x => x.Name, StringComparer.InvariantCultureIgnoreCase) 
     .ToDictionary(g => g.Key, g => g.First().Value, StringComparer.InvariantCultureIgnoreCase); 
    return result; 
} 

我帶的第一個值出來的複製品。但是你可以改變邏輯。

相關問題