搜索列表和订单按值列出最大值找到c#

时间:2012-07-09 13:09:16

标签: c# linq

我想承认我在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,然后是无与伦比的休息。我需要改变你的代码。请帮忙。感谢

3 个答案:

答案 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);