如何通过linq数据的每一行中出现的单词对列表进行排序?我从这里得到了一个给出正确输出的人的答案。这是代码:
void Main()
{
List<SearchResult> list = new List<SearchResult>() {
new SearchResult(){ID=1,Title="Geo Prism GEO 1995 GEO* - ABS #16213899"},
new SearchResult(){ID=2,Title="Excavator JCB - ECU P/N: 728/35700"},
new SearchResult(){ID=3,Title="Geo Prism GEO 1995 - ABS #16213899"},
new SearchResult(){ID=4,Title="JCB Excavator JCB- ECU P/N: 728/35700"},
new SearchResult(){ID=5,Title="Geo Prism GEO,GEO 1995 - ABS #16213899 GEO"},
new SearchResult(){ID=6,Title="dog"},
};
var to_search = new[] { "Geo", "JCB" };
var result = from searchResult in list
let key_string = to_search.FirstOrDefault(ts => searchResult.Title.ToLower().Contains(ts.ToLower()))
group searchResult by key_string into Group
orderby Group.Count() descending
select Group;
result.ToList().Dump();
}
// Define other methods and classes here
public class SearchResult
{
public int ID { get; set; }
public string Title { get; set; }
}
我得到了像
这样的输出ID Title
-- ------
1 Geo Prism GEO 1995 GEO* - ABS #16213899
3 Geo Prism GEO 1995 - ABS #16213899
5 Geo Prism GEO,GEO 1995 - ABS #16213899 GEO
2 Excavator JCB - ECU P/N: 728/35700
4 JCB Excavator JCB- ECU P/N: 728/35700
6 dog
以上输出没问题。具有ord GEO的所有行首先出现,因为它在大多数行中找到最大时间意味着GEO在3行中找到该字,而JCB在两行中找到,因此接下来是JCB相关行。
在获得整个数据的上述输出后,我需要另一种排序。那就是GEO行首先出现哪一行具有GEO字最大时间。所以我的输出如下所示:
ID Title
-- ------
5 Geo Prism GEO,GEO 1995 - ABS #16213899 GEO
1 Geo Prism GEO 1995 GEO* - ABS #16213899
3 Geo Prism GEO 1995 - ABS #16213899
4 JCB Excavator JCB- ECU P/N: 728/35700
2 Excavator JCB - ECU P/N: 728/35700
6 dog
我找到了一个linq查询,用于计算字符串中单词的出现次数:
string text = @"Historically, the world of data and data the world of objects data" ;
string searchTerm = "data";
//Convert the string into an array of words
string[] source = text.Split(new char[] { '.', '?', '!', ' ', ';', ':', ',' }, StringSplitOptions.RemoveEmptyEntries);
var matchQuery = from word in source
where word.ToLowerInvariant() == searchTerm.ToLowerInvariant()
select word;
int wordCount = matchQuery.Count();
我是从this url
得到的我如何使用上面的代码对我的标题进行排序?如何使用第二种排序来计算标题字段中单词的出现次数,结果我的输出看起来像:
ID Title
-- ------
5 Geo Prism GEO,GEO 1995 - ABS #16213899 GEO
1 Geo Prism GEO 1995 GEO* - ABS #16213899
3 Geo Prism GEO 1995 - ABS #16213899
4 JCB Excavator JCB- ECU P/N: 728/35700
2 Excavator JCB - ECU P/N: 728/35700
6 dog
答案 0 :(得分:1)
使用WordCount作为字符串的扩展方法,然后可以使用简单的Lambda表达式:
list.OrderByDescending(sR => sR.Title.WordCount( to_search ))
如果您想省略所有没有搜索字词的结果,可以使用Where
子句。即。
IEnumerable<SearchResult> results = list
.Where( sR => sR.Title.WordCount( searchTerms ) > 0 )
.OrderByDescending( sR => sR.Title.WordCount( searchTerms ) );
修改强> 如果搜索条件对它们有优先权,您可以对每个项目进行多种排序(首先按最低优先级元素排序,然后是下一个,直到最终排序位于具有最高优先级的项目上):
string[] searchTerms = new string[]{ "GEO","JCB" };
IEnumerable<SearchResult> results = list;
foreach( string s in searchTerms.Reverse() ) {
results = results
.OrderByDescending( sR => sR.Title.WordCount( s ) );
}
扩展方法:
static class StringExtension{
public static int WordCount( this String text, string searchTerm )
{
string[] source = text.Split( new char[] { '.', '?', '!', ' ', ';', ':', ',' }, StringSplitOptions.RemoveEmptyEntries );
var matchQuery = from word in source
where word.ToLowerInvariant() == searchTerm.ToLowerInvariant()
select word;
int wordCount = matchQuery.Count();
return wordCount;
}
public static int WordCount( this String text, IEnumerable<string> searchTerms ) {
int wordCount = 0;
foreach( string searchTerm in searchTerms ) {
wordCount += text.WordCount( searchTerm );
}
return wordCount;
}
}
答案 1 :(得分:1)
这个怎么样:
IEnumerable<SearchResult> result =
from searchResult in list
let key_string = to_search.FirstOrDefault(ts => searchResult.Title.ToLower().Contains(ts.ToLower()))
group searchResult by key_string into Group
orderby Group.Count() descending
from item in Group.OrderByDescending(theItem => WordCount(theItem.Title, Group.Key))
select item;
使用以下WordCount
方法:
public static int WordCount( String text, string searchTerm )
{
string[] source = text.Split( new char[] { '.', '?', '!', ' ', ';', ':', ',' }, StringSplitOptions.RemoveEmptyEntries );
var matchQuery = from word in source
where word.ToLowerInvariant() == searchTerm.ToLowerInvariant()
select word;
int wordCount = matchQuery.Count();
return wordCount;
}
我注意到的一个小问题是,不包含匹配单词的标题将被组合在一起,因此可以将它们放在具有匹配单词的标题前面。
答案 2 :(得分:0)
这一行之后:
var result = from searchResult in list
let key_string = to_search.FirstOrDefault(ts => searchResult.Title.ToLower().Contains(ts.ToLower()))
group searchResult by key_string into Group
orderby Group.Count() descending
select Group;
你想要这样的东西:
foreach (var group in result) {
foreach (var item in group.OrderByDescending(theItem => WordCount(theItem.Title, group.Key))) {
Console.WriteLine(item.Title);
}
}
添加的方法如下:
public static int WordCount(string haystack, string needle) {
if (needle == null) {
return 0;
}
string[] source = haystack.Split(new char[] { '.', '?', '!', ' ', ';', ':', ',' }, StringSplitOptions.RemoveEmptyEntries);
var matchQuery = from word in source
where word.ToLowerInvariant() == needle.ToLowerInvariant()
select word;
return matchQuery.Count();
}