Processing a C# Dictionary using LINQ

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17490378/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 09:38:02  来源:igfitidea点击:

Processing a C# Dictionary using LINQ

c#linq

提问by Sriram B

How do I write the "// Display using Foreach" loop implementation using LINQ Lambda Expression / Statemene Expression?

How do I write the "// Display using Foreach" loop implementation using LINQ Lambda Expression / Statemene Expression?

I want to simplify my development and avoid nested foreach loops as much as possible. I am trying to include more logic with in the second foreach statement and I want to use Lambda / Statement expression.

I want to simplify my development and avoid nested foreach loops as much as possible. I am trying to include more logic with in the second foreach statement and I want to use 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();
    }

Please suggest.

Please suggest.

采纳答案by Sergey Berezovskiy

If you want to group countries by code, then you don't need two dictionaries. Use Enumerable.GroupBy

If you want to group countries by code, then you don't need two dictionaries. Use Enumerable.GroupBy

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

    Console.WriteLine();
}

Or just use your countriesDictionary(it already has countries grouped by code):

Or just use your countriesDictionary(it already has countries grouped by code):

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

    Console.WriteLine();
}

回答by Theraot

This is another alternative:

This is another alternative:

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


Also, this one based on Romoku's Answer(the answer was removed):

Also, this one based on Romoku's Answer(the answer was removed):

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

回答by Jamie - Fenrir Digital Ltd

Or just make it very easy... as already mentioned, you're already grouping by Country code...

Or just make it very easy... as already mentioned, you're already grouping by Country code...

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

回答by ígor

I will use a extension to do it.

I will use a extension to do it.

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

回答by terrybozzio

One way could be like this,avoiding the first foreach with GroupBy,the just 1 foreach logic to print each country name with specified code:

One way could be like this,avoiding the first foreach with GroupBy,the just 1 foreach logic to print each country name with specified code:

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

回答by MadHenchbot

Though you probably have enough answers for the time being, this LINQ will compress your dictionary into a list of country names, allowing an easy foreach to display them.

Though you probably have enough answers for the time being, this LINQ will compress your dictionary into a list of country names, allowing an easy foreach to display them.

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

But the way your Dictionary is set up, the key should always match the country codes in the value, correct?

But the way your Dictionary is set up, the key should always match the country codes in the value, correct?