C# Linq - 按相同 属性 的计数对 IEnumerable 进行排序

C# Linq - order IEnumerable by count of identical property

我试图找到一个 Linq 表达式,我可以在其中订购由

组成的 IEnumerable

string 国家 串城 bool IsCapital

新的 IEnumerable 列出所有对象的方式,但顺序是

  1. 县,但首先是列表中城市最多的国家,然后是条目第二多的国家,依此类推
  2. 然后按城市

我的第一次尝试是

IEnumerable allCities = new Enumerable { 
//initialize list
};

allCities = allCities
.OrderBy(x => x.Country)
.ThenBy(x.City);

但当然不考虑同一国家/地区的城市数量。

感谢您的帮助,在此先感谢您。

马丁

您可以将 Linq GroupBy() 方法用作:

// 1. Group by country
// 2. Order descending by the count of each group
// 3. Select all objects of all groups (ordered) to a flat list
var result = cities
    .GroupBy(x => x.Country)
    .OrderByDescending(grp => grp.Count())
    .SelectMany(grp => grp.OrderBy(x => x.City))
    .ToList();

此对象列表:

var cities = new List<MyObj>
{
    new MyObj { Country = "Germany", City = "Frankfurt" },
    new MyObj { Country = "Norway", City = "Oslo" },
    new MyObj { Country = "Italy", City = "Rome" },
    new MyObj { Country = "Germany", City = "Berlin" },
    new MyObj { Country = "Germany", City = "Munich" },
    new MyObj { Country = "France", City = "Paris" },
    new MyObj { Country = "Italy", City = "Milano" },
};

...将给出结果:

德国 - 柏林
德国 - 法兰克福
德国 - 慕尼黑
意大利 - 米兰
意大利 - 罗马
挪威 - 奥斯陆
法国 - 巴黎

为此你需要Counties with their zero or more Cities的概念。完成后,您可以按城市数量对县进行排序,并按县对城市进行排序。

结果:对县进行排序(按城市数量降序排列),每个城市按名称排序

如果您想将其拼合为 [County, City, IsCapital] 的组合,您可以使用 SelectMany 来执行此操作。

首先,您必须按同一个县对所有项目进行分组。唉,你忘了给你的 [County, City, IsCapital] 起一个 class 的名字,所以我给它起名字 GeographicalItem

IEnumerable<GeographicalItem> inputData = ...

Counties with their Cities 进行分组:

var result = inputData.GroupBy(geographicalItem => geographicalItem.County,

// parameter resultSelector: for every Country, with all geograhpicalItems in this
// country make one "Country with its cities"
(country, geographicalItemsInThisCountry) => new
{
    Country = country,
    Cities = geoghraphicalItemsInThisCountry.Select(geographicalItem => new
    {
        Name = geographicalItem.City,
        IsCapital = geograhpicalItem.IsCapital,
    })
    .OrderBy(city => city.Name)
    .ToList(),
})

结果:国家序列,每个国家都有该国家的城市列表,按名称排序。每个城市都有一个名称和一个 属性 IsCapital。

现在按国家:城市最多的国家排序:

继续 LINQ:

.OrderByDescending(country => country.Cities.Count)

结果:已排序的国家/地区,每个国家/地区及其已排序的城市。首先是拥有最多城市的国家。按名称排序的国家/地区内的城市。

如果你想压平结果:使用 SelectMany:

.SelectMany(county => country.Cities,

// parameter resultSelector: from every [country, city] combination make one new:
(country, city) => new
{
    Country = country,
    City = city.Name,
    IsCapital = city.IsCapital,
});