2012-01-03 20 views
1

我有一个Dictionary类型IDictionary<string, Country>,其0123,是城市的名称和值是Enum类型Country如何使以下C#GroupBy功能更好?

项目在这本字典看起来像这些:< “温哥华”,Country.Canada>,< “西雅图”,Country.US>,< “纽约”,Country.US>等

我需要按照价值(即国家)对词典中的所有项目进行分组。输出字符串是这样的:

“美国城市:西雅图,纽约” “加拿大城市:温哥华”

这里是我写的东西:

public void GroupByCountry(IEnumerable<KeyValuePair<string, Country>> dict) 
{ 
    string text = string.Empty; 
    var groups = dict.GroupBy(p => p.Value, p => p.Key); 
    foreach (var g in groups) 
    { 
     List<string> citiesInGroup = new List<string>(); 
     foreach (string city in g) 
     { 
      citiesInGroup.Add(ext); 
     } 
     text += string.Format("{0}: {1}\n", Enum.GetName(typeof(Country), g.Key), string.Join("|", citiesInGroup.ToArray())); 
    } 
    Log.Info(logCategory, string.Format("Result:\n{0}", text)); 
} 

此代码的工作。但我想知道它是否可以更简洁和优雅?

回答

4

这听起来像你想有一个Lookup

Lookup<Country, string> lookup = dict.ToLookup(pair => pair.Value, 
               pair => pair.Key); 

目前尚不清楚你所需要的,结果做的事情 - 如果它只是格式,你可以使用string.Join与投影...但我假设你确实需要做更有趣的事情。

+0

难道你不能以许多城市的“钥匙”结束吗?或者'ToLookUp'处理这种情况? – hunter 2012-01-03 18:10:42

+0

@hunter:不知道你的意思是什么 - 但如果它是以'Dictionary '开头的,那么每个城市只能有一对。 – 2012-01-03 18:12:23

+1

呜呼,这个问题引起了Jon的注意!稍后我会尝试您的建议。 – sean717 2012-01-03 18:22:41

3

反过来会不会更容易?

IDictionary<Country, IList<string>>

似乎更有意义,在存储项目的层次结构。

+0

是的,它的作用。但当我交给我时就是这样。我不是那个设计它的人:) – sean717 2012-01-03 18:20:41

2

这是你想要的吗?

from de in dict 
group de by de.Value into dg 
select String.Join("\n", dg.Key + ": " + 
    String.Join("|", dg.Select(v => v.Key)) 
); 
1

随着乔恩斯基特的回答,这可能是你完美的解决方案

Lookup<Country,String> lookup = (Lookup<Country,String>) dict.ToLookup(pair => pair.Value, 
                      pair => pair.Key); 
foreach (var a in lookup) 
    { 
     strOutput += string.Format("{0}:{1} ", a.Key, 
            string.Join(",", a.Select(s => s))); 
    }