Reputation: 691
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.
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.
Upvotes: 25
Views: 66686
Reputation: 40170
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):
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();
}
Upvotes: 25
Reputation: 1385
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?
Upvotes: 3
Reputation: 4542
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();
Upvotes: 1
Reputation: 1164
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);
});
}
}
Upvotes: 0
Reputation: 1397
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);
}
Upvotes: 1
Reputation: 236218
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):
foreach(var kvp in countriesDictionary)
{
foreach(var country in kvp.Value)
Console.WriteLine(country.CountryName);
Console.WriteLine();
}
Upvotes: 6