简体   繁体   English

使用LINQ在组内排序

[英]Ordering within groups using LINQ

Given the following data: 鉴于以下数据:

List<Country> countries = new List<Country>();

countries.Add(new Country{ Name = "USA",     population=500000,  Year=2012 });
countries.Add(new Country{ Name = "USA",     population=300000,  Year=2002 });
countries.Add(new Country{ Name = "USA",     population=250000,  Year=1992 });
countries.Add(new Country{ Name = "USA",     population=20000,   Year=1982 });

countries.Add(new Country{ Name = "India",   population=1500000, Year=2012 });
countries.Add(new Country{ Name = "India",   population=1000000, Year=2002 });
countries.Add(new Country{ Name = "India",   population=50000,   Year=1982 });
countries.Add(new Country{ Name = "India",   population=80000,   Year=1992 });

countries.Add(new Country{ Name = "Germany", population=100000,  Year=2012 });
countries.Add(new Country{ Name = "Germany", population=400000,  Year=2002 });
countries.Add(new Country{ Name = "Germany", population=60000,   Year=1992 });
countries.Add(new Country{ Name = "Germany", population=4000,    Year=1982 });

countries.Add(new Country{ Name = "UK",      population=450000,  Year=2002 });
countries.Add(new Country{ Name = "UK",      population=50000,   Year=1992 });
countries.Add(new Country{ Name = "UK",      population=3000,    Year=1982 });  

I want to order the countries by the largest population for a given year, but then display all the years for that country before moving on to the next country. 我希望按照一年中最大的人口订购这些国家,但随后显示该国家的所有年份,然后再转移到下一个国家。

Eg 例如

  1. 2012 - the population order would be India, USA, UK, Germany. 2012年 - 人口订单将是印度,美国,英国,德国。 So I would like the data to be ordered by all India data, all USA data, all UK data and then Germany. 所以我希望所有印度数据,所有美国数据,所有英国数据和德国都能订购数据。

  2. 2002 - the population order would be India, USA, Germany and then UK. 2002年 - 人口订单将是印度,美国,德国和英国。 UK is last because it has no 2002 data. 英国是最后一次,因为它没有2002年的数据。

I want to achieve this using LINQ, although I've used LINQ in the past I'm struggling to get my head around this. 我想用LINQ来实现这一点,虽然我过去使用过LINQ,但我很难理解这一点。 Any help would be much appreciated. 任何帮助将非常感激。

You need to group the data by country and then order by population for a particular year; 您需要按国家/地区对数据进行分组,然后按特定年份的人口排序;

var year = 2002;    

var orderedCountries = countries
                        .GroupBy(c => c.Name)
                            .OrderByDescending(c => c.Where(y => y.Year == year).Select(p => p.population).FirstOrDefault())
                                .SelectMany(c=>c)  
                                .ToList();

The above code will work even if there is no data for a given year 即使没有给定年份的数据,上述代码也能正常工作

That can be a bit much to read so you could separate out the logic in the orderby into a delegate eg; 这可能有点多,因此您可以将orderby中的逻辑分离为委托,例如;

var orderedCountries = countries
                            .GroupBy(c => c.Name)
                                .OrderByDescending(c => GetPop(c, year))
                                    .SelectMany(c=>c)  
                                        .ToList();

Func<IGrouping<string, Country>, int, long> GetPop = 
                                    ((cntry, yr) => (from c in cntry
                                                     where c.Year == yr
                                                     select c.population).First());

This is quite equivalent to saj's answer, but using query syntax: 这与saj的答案完全相同,但使用查询语法:

var y = 2002;

var ordered = 
    from c in countries
    group c by c.Name into g
    select new
    {
        Name = g.Key,
        Population = (
            from x in g
            where x.Year == y
            select x.population).FirstOrDefault()
    } into s
    orderby s.Population descending
    join f in countries
    on s.Name equals f.Name
    select f;

There is a similar question asked here: Multiple "order by" in LINQ 这里有一个类似的问题: LINQ中有多个“order by”

Something like this would do the trick in your case. 在你的情况下,像这样的东西会成功。 I tested it in VS and it works as expected: 我在VS中测试了它,它按预期工作:

var countries order= countries.OrderBy(c => c.Year).ThenBy(n => n.population);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM