【问题标题】:Processing a C# Dictionary using LINQ使用 LINQ 处理 C# 字典
【发布时间】:2018-05-23 07:38:49
【问题描述】:

如何使用 LINQ Lambda 表达式/Statemene 表达式编写“// 使用 Foreach 显示”循环实现?

我想简化我的开发并尽可能避免嵌套的 foreach 循环。我试图在第二个 foreach 语句中包含更多逻辑,并且我想使用 Lambda / Statement 表达式。

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

请提出建议。

【问题讨论】:

  • 你已经在countriesDictionary字典中过滤了国家,你为什么在嵌套循环中搜索dCountries

标签: c# linq


【解决方案1】:

这是另一种选择:

countriesDictionary.ToList().ForEach
(
    pair =>
    {
        pair.Value.ForEach(country => Console.WriteLine(country.CountryName));
        Console.WriteLine();
    }
);

另外,这个基于Romoku's Answer(答案被删除):

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

【讨论】:

    【解决方案2】:

    如果您想按代码对国家/地区进行分组,则不需要两个字典。使用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);
      

      但是您的字典设置方式,键应该始终与值中的国家/地区代码匹配,对吗?

      【讨论】:

        【解决方案4】:

        或者只是让它变得非常简单...如前所述,您已经按国家/地区代码分组...

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

        【讨论】:

          【解决方案5】:

          一种方法可以是这样,避免使用 GroupBy 的第一个 foreach,仅使用 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();
          

          【讨论】:

            【解决方案6】:

            我将使用扩展来做到这一点。

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-02-02
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多