使用LINQ处理C#字典
本文关键字:字典 处理 LINQ 使用 | 更新日期: 2023-09-27 18:21:06
如何使用LINQ Lambda Expression/Statemene Expression编写"//使用Foreach显示"循环实现?
我想简化我的开发,并尽可能避免嵌套的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();
}
请提出建议。
这是另一种选择:
countriesDictionary.ToList().ForEach
(
pair =>
{
pair.Value.ForEach(country => Console.WriteLine(country.CountryName));
Console.WriteLine();
}
);
此外,这一个基于Romoku的答案(答案被删除):
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();
}
如果要按代码对国家/地区进行分组,则不需要两个字典。使用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();
}
虽然您可能暂时有足够的答案,但这个LINQ将把您的字典压缩成一个国家名称列表,允许foreach轻松显示它们。
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);
但是按照字典的设置方式,关键字应该始终与值中的国家代码相匹配,对吗?
或者让它变得非常简单。。。如前所述,您已经按国家代码进行了分组。。。
foreach (var country in countriesDictionary.SelectMany(pair => pair.Value))
{
Console.WriteLine(country.CountryName);
}
一种方法可以是这样的,避免使用GroupBy的第一个foreach,即只需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();
我将使用一个扩展来完成它。
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);
});
}
}