2013-07-05 2 views
10

Как написать реализацию цикла «// Отображение с использованием Foreach» с использованием выражения LINQ Lambda Expression/Statemene Expression?Обработка словаря C# с использованием LINQ

Я хочу упростить свое развитие и максимально избегать вложенных петлей 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(); 
    } 

Прошу предложить.

+5

Вы уже отфильтровали страны в словаре 'countriesDictionary', почему вы ищете в' dCountries' в вложенном цикле? –

ответ

5

Если вы хотите сгруппировать страны по коду, вам не нужны два словаря. Используйте 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(); 
} 
10

Это еще одна альтернатива:

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

Кроме того, этот основанный на Romoku's Answer (a nswer был удален):

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

var dCountries = new List<Country>(); 

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

Или просто сделать это очень легко ... как уже было сказано, вы уже группируя код страны ...

 foreach (var country in countriesDictionary.SelectMany(pair => pair.Value)) 
     { 
      Console.WriteLine(country.CountryName); 
     } 
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); 
      }); 
     } 
    } 
1

Одним из способов может быть, как это, избегая первый Еогеасп с GroupBy, логика просто 1 Еогеасп напечатать каждое название страны с указанным кодом:

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

Хотя вы, вероятно, достаточно найти ответы на время, эта LINQ сжимает ваш словарь в список названий стран, что позволяет легко отображать их.

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

Но как ваш словарь установлен, ключ всегда должен соответствовать кодам стран в значении, правильно?

Смежные вопросы