我有以下代码从字符串中提取关键字:
var results = text.Split(new char[]{' ',',','.','!','?','_',':',';','/','(',')','\n','\r','-','*','"','/','\\','$','%','+','-','='}) // default split by whitespace
.GroupBy(str => str) // group words by the value
.Select(g => new
{
str = g.Key, // the value
count = g.Count() // the count of that value
});
现在我需要为其添加OrderByDescending
,但不确定将其放置在何处。
.GroupBy(str => str).OrderByDescending(count => count)
产生了错误的结果。怎么做对了?
答案 0 :(得分:4)
您可以在选择后添加它。
.Select(...whatever...).OrderByDescending(item => item.count);
答案 1 :(得分:2)
在GroupBy之后使用它并以g.Count()
语句中的方式调用Select
:
.GroupBy(str => str)
.OrderByDescending(g => g.Count())
.Select(g => new ...) // rest of your code here
编辑:我实际上更喜欢Anthony's answer我自己并且即将修改我的,但到那时他已经发布了他的回复。这是一个非常小的问题并且是一个过早的优化,但是我处理大型集合时我的发布方法会稍微慢一点,因为Count()
正在执行两次,而Anthony的方法是对已经计算的Count()
进行排序在Select
声明中。在构建干净的LINQ查询时,请记住一些事项。
顺便说一下,在查询语法中,我们可以通过将计数存储在let
中来确定这一点(当然,这可以通过流畅的语法实现,但在查询语法中感觉更自然),这将提供良好的性能。像这样:
var query = from g in text.Split(...).GroupBy(str => str)
let count = g.Count()
orderby count descending
select new { str = g.Key, Count = count };
答案 2 :(得分:2)
您误解的原因是您在lambda中为变量赋予与匿名类型上的属性相同的名称。 OrderByDescending(count => count)
对整个对象进行排序。你想要的是对count属性进行排序,所以你应该使用OrderByDescending(x => x.count)
。