我想承认我在LINQ中很弱。 我有数据列表。我希望按给定值搜索列表,然后按最大出现次数对数据进行排序,这意味着行中的最大时间。
List<SearchResult> list = new List<SearchResult>() {
new SearchResult(){ID=1,Title="Cat"},
new SearchResult(){ID=2,Title="dog"},
new SearchResult(){ID=3,Title="Tiger"},
new SearchResult(){ID=4,Title="Cat"},
new SearchResult(){ID=5,Title="cat"},
new SearchResult(){ID=6,Title="dog"},
};
如果我搜索&amp;排序列表中包含&#34;狗猫&#34; 等数据,然后输出就像
ID=1,Title=Cat
ID=4,Title=Cat
ID=5,Title=Cat
ID=2,Title=dog
ID=6,Title=dog
所有猫都会先来,因为这个cat关键字在所有行中找到了最长时间,然后狗找到了最长时间。
以下数据不会出现,因为它不在搜索字词
中ID=3,Title=Tiger
寻找解决方案。感谢
List<SearchResult> list = new List<SearchResult>() {
new SearchResult(){ID=1,Title="Geo Prism 1995 - ABS #16213899"},
new SearchResult(){ID=2,Title="Excavator JCB - ECU P/N: 728/35700"},
new SearchResult(){ID=3,Title="Geo Prism 1995 - ABS #16213899"},
new SearchResult(){ID=4,Title="JCB Excavator - ECU P/N: 728/35700"},
new SearchResult(){ID=5,Title="Geo Prism 1995 - ABS #16213899"},
new SearchResult(){ID=6,Title="dog"},
};
var to_search = new[] { "Geo", "JCB" };
var result = list.Where(sr => to_search.Any(ts => String.Compare(ts, sr.Title, StringComparison.OrdinalIgnoreCase) == 0))
.GroupBy(sr => sr.Title.ToLower())
.OrderByDescending(g => g.Count());
var matched = result.SelectMany(m => m);
var completeList = matched.Concat(list.Except(matched));
dataGridView2.DataSource = completeList.ToList();
我尝试在另一个应用程序中使用您的逻辑,但它无效。根据逻辑,三行首先带有GEO关键字,然后接下来的两行带有JCB,然后是无与伦比的休息。我需要改变你的代码。请帮忙。感谢
答案 0 :(得分:3)
这会过滤您的列表并按Title
对其进行分组,按照大小对组进行排序。
List<SearchResult> list = new List<SearchResult>() {
new SearchResult(){ID=1,Title="Cat"},
new SearchResult(){ID=2,Title="dog"},
new SearchResult(){ID=3,Title="Tiger"},
new SearchResult(){ID=4,Title="Cat"},
new SearchResult(){ID=5,Title="cat"},
new SearchResult(){ID=6,Title="dog"},
};
var to_search = new[] { "cat", "dog" };
var result = list.Where(sr => to_search.Any(ts => String.Compare(ts, sr.Title, StringComparison.OrdinalIgnoreCase) == 0))
.GroupBy(sr => sr.Title.ToLower())
.OrderByDescending(g => g.Count());
foreach (var group in result)
foreach (var element in group)
Debug.WriteLine(String.Format("ID={0},Title={1}", element.ID, element.Title));
<强>输出:强>
ID=1,Title=Cat
ID=4,Title=Cat
ID=5,Title=cat
ID=2,Title=dog
ID=6,Title=dog
如果您不关心实际的分组,可以使用SelectMany展平群组列表。
(请注意,此代码将忽略Title
的情况。我不知道这是否是您想要的,或者是否是代码中的拼写错误:您正在使用cat
和{{ 1}},在您的输出中只有Cat
,但Cat
没有大写。)
修改强>
要获取不匹配的项目,您可以使用Except:
dog
编辑2:
var unmatched = list.Except(result.SelectMany(m => m)); // beware! contains the tiger!
<强>输出强>
var result = list.Where(sr => to_search.Any(ts => String.Compare(ts, sr.Title, StringComparison.OrdinalIgnoreCase) == 0))
.GroupBy(sr => sr.Title.ToLower())
.OrderByDescending(g => g.Count());
var matched = result.SelectMany(m => m);
var completeList = matched.Concat(list.Except(matched));
foreach (var element in completeList)
Debug.WriteLine(String.Format("ID={0},Title={1}", element.ID, element.Title));
编辑3
ID=1,Title=Cat
ID=4,Title=Cat
ID=5,Title=cat
ID=2,Title=dog
ID=6,Title=dog
ID=3,Title=Tiger
答案 1 :(得分:1)
我认为以下应该可以解决问题。
var searchText = "cat dog";
var searchResult = list
.Select(i => new {
Item = i,
Count = list.Count(x => string.Compare(x.Title, i.Title, true) == 0) // Add counter
})
.Where(i => searchText.Contains(i.Item.Title))
.OrderByDescending(i => i.Count)
.ThenBy(i => i.Item.ID)
.ToList()
<强>更新强>
如果你想在最后得到不匹配的数据,你需要在匿名对象中添加另一个排序属性。
var searchText = "cat dog";
var searchResult = list
.Select(i => new {
Item = i,
Matched = searchText.Contains(i.Item.Title.ToUpper()),
Count = list.Count(x => string.Compare(x.Title, i.Title, true) == 0) // Add counter
})
.OrderByDescending(i => i.Matched)
.ThenBy(i => i.Count)
.ThenBy(i => i.Item.ID)
.ToList()
答案 2 :(得分:1)
IEnumerable<string> pets = new[] { "Cat", "dog", "Tiger", "Cat", "cat", "dog" };
var test = pets
.Where(p=>p.ToUpperInvariant() == "CAT" || p.ToUpperInvariant() == "DOG")
.GroupBy(p => p.ToUpperInvariant())
.OrderByDescending(g => g.Count())
.SelectMany(p => p);
foreach (string pet in test)
Console.WriteLine(pet);