C# 如果字典包含具有相同键的项,如何使用LINQ更新字典?

C# 如果字典包含具有相同键的项,如何使用LINQ更新字典?,c#,linq,dictionary,C#,Linq,Dictionary,我有下一个功能: 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, S

我有下一个功能:

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);
}

但是我需要重写这个项目。如何使用LINQ实现这一点?很抱歉我的问题很愚蠢,如果回答起来很容易的话。

您可以选择不同的cookies以避免重复的字典键。但是,当然,在结果字典中只有一个值。也就是说,如果您有像
“Hello”
“Hello”
“Hello”
这样的cookie,那么如果您使用忽略大小写比较,则无法放置所有这些键。下面的解决方案只选择与忽略的大小写相同的第一个值(即,在这种情况下只添加
“Hello”
键):

顺便说一句,代码可以简化为

return cc.AllKeys // use .Cast<string>() if need
         .Distinct(StringComparer.InvariantCultureIgnoreCase) 
         .ToDictionary(cookie => cookie,
                       cookie => (object)cc[cookie]);
返回cc.AllKeys//use.Cast()(如果需要)
.Distinct(StringComparer.InvariantCultureInogoreCase)
.ToDictionary(cookie=>cookie,
cookie=>(对象)cc[cookie]);

因此,您将避免创建匿名对象。

我可能会出错,但我认为使用LINQ无法做到这一点。 return语句创建一个新字典,该字典将从cookie集合中的对象创建。如果此集合包含多个同名对象,则会出现问题

我认为实现这一点的最佳方法是迭代cookie集合,手动为字典创建对象,然后使用索引器语法在字典中设置它们:

dictionary[cookiename] = cookieValue;
干杯


Alex

可能您有重复的名称,您可以使用相同的
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;
}
来自cookies的私有静态字典(HttpCookieCollection cc)
{
var result=cc.AllKeys
.Select(cookie=>new{Name=cookie,Value=(对象)cc[cookie]})
.GroupBy(x=>x.Name,StringComparer.InvariantCultureInogoreCase)
.ToDictionary(g=>g.Key,g=>g.First().Value,StringComparer.InvariantCultureIgnoreCase);
返回结果;
}

我从副本中取出第一个值。但是您可以更改逻辑。

您可以始终使用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]));
        }
私有静态IEnumerable FromCookies(HttpCookieCollection cc)
{
返回(从cc.AllKeys中的字符串cookie选择新的KeyValuePair(cookie,cc[cookie]);
}

当两个cookie具有相同的名称时,您可以从明确指定希望发生什么开始。@Jon确切地说,这并不像拉出所有不重复的键那么简单。@Lewsterin我在Visual Studio 2010中工作Ultimate@Jon我想用新的值替换旧的cookie值。@matterai:哪一个是新的值?“cookie”或“cookie”较新吗?这将如何工作?具有相同键和不同值的cookie会发生什么情况?我正处于否决票的边缘,因为这可能会或可能不会像OP希望的那样起作用,它显然仍然存在问题,但没有试图得到澄清。@Jon OP通过
cc[cookie]
检索值,因此值也将是相同的“Hello”,如果字典中同时存在“Hello”,则“Hello”将打破这一点。@BasBrekelmans同意,但是没有办法将两者都放在使用不变大小写的字典中,这可以使用LINQ来完成,OP只需要更具体地说明如果存在重复项,他们希望发生什么。“但是我需要重写此项。”->听起来OP想要替换前一个对象。我已经完成了。但是我用了foreach。我在每个循环中检查字典是否包含equals KeyValuePair。因此,如果它包含,我将用新的替换它。公平地说,如果您只想处理重复:-)值得记住,尽管该字典实际上实现了IEnumerable,因此该字典的限制性更强。您可能还想浏览一下查找:如果您想修改缓存的副本,则不太好。。。
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;
}
private static IEnumerable<KeyValuePair<string, object>> FromCookies(HttpCookieCollection cc)
        {
            return (from string cookie in cc.AllKeys select new KeyValuePair<string,object>(cookie, cc[cookie]));
        }