使用LINQ在组内排序

时间:2012-10-03 15:52:09

标签: c# linq

鉴于以下数据:

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 });  

我希望按照一年中人口最多的国家订购这些国家,然后显示该国家的所有年份,然后再转移到下一个国家。

E.g。

  1. 2012年 - 人口订单将是印度,美国,英国,德国。所以我希望所有印度数据,所有美国数据,所有英国数据以及德国都能订购数据。

  2. 2002年 - 人口订单将是印度,美国,德国和英国。英国是最后一个,因为它没有2002年的数据。

  3. 我想用LINQ实现这一点,虽然我过去使用过LINQ,但我很难理解这一点。任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:4)

您需要按国家/地区对数据进行分组,然后按特定年份的人口排序;

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();

即使某一年没有数据

,上述代码也能正常运行

这可能有点多,所以你可以把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());

答案 1 :(得分:0)

这完全等同于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;

答案 2 :(得分:-1)

这里有一个类似的问题: Multiple "order by" in LINQ

这样的事情可以解决你的问题。我在VS中进行了测试,它按预期工作:

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