2013-07-05 4 views
10

Wie schreibe ich die "// Display using Foreach" -Schleifenimplementierung unter Verwendung von LINQ Lambda Expression/Statemene Expression?Verarbeiten eines C# -Wörterbuchs unter Verwendung von LINQ

Ich möchte meine Entwicklung vereinfachen und verschachtelte foreach-Schleifen so weit wie möglich vermeiden. Ich versuche, in der zweiten foreach-Anweisung mehr Logik einzubeziehen, und ich möchte Lambda/Statement-Ausdruck verwenden.

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

Bitte vorschlagen.

+5

Sie haben bereits Länder im 'countriesDictionary' Wörterbuch gefiltert, warum suchen Sie in' dCountries' in Nested Loop? –

Antwort

5

Wenn Sie Länder nach Code gruppieren möchten, benötigen Sie keine zwei Wörterbücher. Verwenden Enumerable.GroupBy

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

    Console.WriteLine(); 
} 

Oder benutzen Sie einfach Ihre countriesDictionary (es bereits durch Code gruppiert Länder):

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

    Console.WriteLine(); 
} 
10

Dies ist eine weitere Alternative:

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

Auch diese ein basierend auf Romoku's Answer (die a nswer wurde entfernt):

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

Oder einfach machen es sehr einfach ... wie bereits erwähnt, sind Sie bereits durch Ländercode Gruppierung ...

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

ich eine Erweiterung verwenden zu tun es.

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

Eine Möglichkeit, wie dies sein könnte, mit GroupBy den ersten foreach zu vermeiden, die nur 1 foreach Logik jedes Ländernamen mit dem angegebenen Code zu drucken:

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

Obwohl Sie wahrscheinlich genügend Antworten für die Zeit wird dieses LINQ Ihr Wörterbuch in eine Liste von Ländernamen komprimieren, die eine einfache foreach erlauben, sie anzuzeigen.

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

Aber die Art, wie Ihr Wörterbuch eingerichtet ist, sollte der Schlüssel immer die Ländercodes im Wert übereinstimmen, richtig?

Verwandte Themen