Обработка словаря С# с использованием LINQ
Как написать цикл цикла "//Отображение с использованием Foreach" с использованием выражения LINQ Lambda Expression/Statemene Expression?
Я хочу упростить свое развитие и максимально избегать вложенных циклов 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();
}
Просьба предложить.
Ответы
Ответ 1
Если вы хотите группировать страны по коду, вам не нужны два словаря. Используйте 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();
}
Ответ 2
Это еще одна альтернатива:
countriesDictionary.ToList().ForEach
(
pair =>
{
pair.Value.ForEach(country => Console.WriteLine(country.CountryName));
Console.WriteLine();
}
);
Кроме того, на основе Romoku Answer (ответ был удален):
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();
}
Ответ 3
Или просто сделайте это очень просто... как уже упоминалось, вы уже группируете по коду страны...
foreach (var country in countriesDictionary.SelectMany(pair => pair.Value))
{
Console.WriteLine(country.CountryName);
}
Ответ 4
Один из способов может быть таким, избегая первого foreach с GroupBy, только 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();
Ответ 5
Хотя на данный момент у вас, вероятно, достаточно ответов, этот 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);
Но как ваш словарь установлен, ключ всегда должен соответствовать кодам стран в значении, правильно?
Ответ 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);
});
}
}