使用LINQ处理C#字典

24

我该如何使用LINQ Lambda Expression / Statement Expression编写“//使用foreach循环显示”的实现?

我希望简化我的开发,并尽可能避免嵌套foreach循环。我正在尝试在第二个foreach语句中包含更多逻辑,并希望使用Lambda / Statement expression。

 internal class Program
{
    internal class Country
    {
        public string CountryName { get; set; }
        public int CountryCode { get; set; }
    }
    static void Main(string[] args)
    {
        List<Country> countries = new List<Country>()
        {
            new Country{CountryName = "India", CountryCode=1},
            new Country{CountryName = "Andaman Nicobar", CountryCode=1},
            new Country{CountryName = "United States of America",  CountryCode=2},
            new Country{CountryName = "Alaska",  CountryCode=2},
            new Country{CountryName = "Hawaii",  CountryCode=2},
            new Country{CountryName = "United Kingdom", CountryCode=3},
            new Country{CountryName = "Australia", CountryCode=4}
        };

        Dictionary<int, List<Country>> countriesDictionary = new Dictionary<int, List<Country>>();
        foreach (Country country in countries)
        {
            if (!countriesDictionary.ContainsKey(country.CountryCode))
                countriesDictionary.Add(country.CountryCode, new List<Country>());
            countriesDictionary[country.CountryCode].Add(country);                
        }

       // Display using Foreach

        foreach (int key in countriesDictionary.Keys)
        {                             
            List<Country> dCountries = countriesDictionary[key];

            foreach (Country country in dCountries)
            {
                if (country.CountryCode.Equals(key))
                {
                    Console.WriteLine(country.CountryName);
                }                
            }
            Console.WriteLine();            
        }
        Console.ReadLine();
    }
请提供建议。

5
你已经在 countriesDictionary 字典中过滤了国家,为什么还要在嵌套循环中搜索 dCountries - Sergey Berezovskiy
6个回答

24
这是另一种选择:
countriesDictionary.ToList().ForEach
(
    pair =>
    {
        pair.Value.ForEach(country => Console.WriteLine(country.CountryName));
        Console.WriteLine();
    }
);

此外,这个问题基于 Romoku的回答(该回答已被删除):

var countriesDictionary = countries.ToLookup(x => x.CountryCode, x => x);

foreach(var countryGroup in countriesDictionary)
{
    foreach(var country in countryGroup)
    {
        Console.WriteLine(country.CountryName);
    }
    Console.WriteLine();
}

6

如果您想按代码对国家进行分组,则不需要两个字典。可以使用Enumerable.GroupBy

foreach(var codeGroup in countries.GroupBy(c => c.CountryCode))
{
    foreach(var country in codeGroup)
       Console.WriteLine(country.CountryName);

    Console.WriteLine();
}

或者您可以使用 countriesDictionary(它已经按代码分组了国家):

foreach(var kvp in countriesDictionary)
{
    foreach(var country in kvp.Value)
       Console.WriteLine(country.CountryName);

    Console.WriteLine();
}

3
尽管您现在可能已经有足够的答案,但这个 LINQ 将会把您的字典压缩成一个国家名称列表,使得通过简单的 foreach 循环可以轻松地显示它们。
    List<string> countryNames = countriesDictionary.SelectMany(
        pair=>pair.Value.Where(
            country=>country.CountryCode == pair.Key
        ).Select(x=>x.CountryName)).ToList();

    foreach (var name in countryNames)
        Console.WriteLine(name);

但是根据您的字典设置,键应该始终与值中的国家代码相匹配,对吗?

1

或者让它变得非常简单... 如已经提到的那样,您已经按国家代码分组了...

        foreach (var country in countriesDictionary.SelectMany(pair => pair.Value))
        {
            Console.WriteLine(country.CountryName);
        }

1
一种方法可以是这样的,避免使用第一个foreach和GroupBy,只需使用1个foreach逻辑打印每个国家名称及其指定代码:
Dictionary<int, List<Country>> countriesDictionary = countries.GroupBy(g => g.CountryCode).ToDictionary(k => k.Key, k => k.ToList());

foreach (int key in countriesDictionary.Keys)
{
      Console.WriteLine("****Countries with code {0}****",key);
      int count = 0;
      while (count < countriesDictionary[key].Count)
      {
            Console.WriteLine(countriesDictionary[key][count].CountryName);
            count++;
      }
      Console.WriteLine();
}

Console.ReadLine();

0

我会使用一个扩展来完成它。

 static class CountryExtension
    {
        public static void WriteCountriesGroupyCountryCode(this IEnumerable<Country> list)
        {
            int currentCountry=int.MinValue;
            list.OrderBy(c => c.CountryCode).ThenBy(c=>c.CountryName).ToList().ForEach(c =>
            {
                if (currentCountry == int.MinValue)
                {
                    currentCountry = c.CountryCode;
                }
                else if (currentCountry != c.CountryCode)
                {
                    Console.WriteLine();
                    currentCountry = c.CountryCode;
                }
                Console.WriteLine(c.CountryName);
            });
        }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接