【问题标题】:Ordering List data by LINQLINQ 排序列表数据
【发布时间】:2012-07-11 19:58:20
【问题描述】:

这样我正在尝试订购数据

        List<SearchResult> list = new List<SearchResult>() {
        new SearchResult(){ID=1,Title="Geo Prism 1995 GEO GEO- ABS #16213899"},
        new SearchResult(){ID=2,Title="Geo Prism 1995 GEO - ABS #16213899"},
        new SearchResult(){ID=3,Title="Geo Prism 1995 - ABS #16213899"},
        new SearchResult(){ID=3,Title="Geo Prism 1995 - ABS #16213899"},
        new SearchResult(){ID=4,Title="Wie man BBA reman erreicht"},
        new SearchResult(){ID=5,Title="Ersatz Airbags, Gurtstrammer und Auto Körper Teile "},
        new SearchResult(){ID=6,Title="JCB Excavator - ECU P/N: 728/35700"},
        };

        var to_search = new[] { "Geo", "JCB" };
        var result = from searchResult in list
                     let title = searchResult.Title.ToLower()
                     let key_string = to_search.FirstOrDefault(ts => title.Contains(ts))
                     orderby key_string == null ? -1 : title.Split(new[] { key_string }, StringSplitOptions.None).Length descending
                     group searchResult by key_string into Group
                     orderby Group.Count() descending
                     select Group;

        var matched = result.SelectMany(m => m);
        var completeList = matched.Concat(list.Except(matched));
        dataGridView2.DataSource = completeList.ToList();//.SelectMany(x => x).ToList();

数据显示在网格中,但我期望的数据不会出现。

输出即将到来

ID  Title

1   Geo Prism 1995 - ABS #16213899
2   Geo Prism 1995 - ABS #16213899
3   Geo Prism 1995 - ABS #16213899
3   Geo Prism 1995 - ABS #16213899
4   Wie man BBA reman erreicht
5   Ersatz Airbags, Gurtstrammer und Auto Körper Teile 
6   JCB Excavator - ECU P/N: 728/35700

但我想以这种方式显示数据

输出应该是这样的

ID  Title

1   Geo Prism 1995 GEO GEO - ABS #16213899
2   Geo Prism 1995 GEO - ABS #16213899
3   Geo Prism 1995 - ABS #16213899
3   Geo Prism 1995 - ABS #16213899
6   JCB Excavator - ECU P/N: 728/35700
4   Wie man BBA reman erreicht
5   Ersatz Airbags, Gurtstrammer und Auto Körper Teile 

JCB 应该排在所有 GEO 之后,因为我正在使用搜索词对数据进行排序,例如 “地理 jcb” 。 geo 在大多数行的标题中找到。所以那些行首先出现了我的搜索词。所以 geo 是我的搜索词之一,它在所有行标题中呈现最大时间。下一个 jcb 应该出现,因为 jcb 在我的搜索词中,但在输出 jcb 相关行中最后出现。所以告诉我如何更改我的 linq 查询。谢谢

【问题讨论】:

  • 我对你的目标感到困惑。我最初误解了您的问题,但看起来您想要所有项目,但您希望“匹配”的项目过滤到顶部?
  • 同样,那些行将首先出现,这将具有最大的单词出现。第一次排序将类似于在行中找到最长时间的搜索词,然后这些行将首先出现。接下来再次排序,就像哪个排序术语在标题中找到的最大时间将首先出现。需要有两个排序。
  • 是的,我想先提取匹配项,然后对匹配项进行排序....之后将排序数据与不匹配项连接起来。
  • 我很抱歉霍根,我很抱歉在这个 Q/A 中发布了类似的问题。我从不使用 linq 一些使用非常基本的目的,但我的要求非常复杂....这就是我失败、失败和沮丧的原因。所以把这些Q/S放在这里。再次抱歉,感谢您耐心等待。

标签: c# linq


【解决方案1】:
class SearchResult{
    public int ID { get; set; } 
    public string Title{ get; set; }
}

void Main()
{

    List<SearchResult> list = new List<SearchResult>() {
        new SearchResult(){ID=4,Title="Wie man BBA reman erreicht"},
        new SearchResult(){ID=5,Title="Ersatz Airbags, Gurtstrammer und Auto Körper Teile "},
        new SearchResult(){ID=6,Title="JCB Excavator - ECU P/N: 728/35700"},
        new SearchResult(){ID=2,Title="Geo Prism 1995 GEO - ABS #16213899"},
        new SearchResult(){ID=3,Title="Geo Prism 1995 - ABS #16213899"},
        new SearchResult(){ID=1,Title="Geo Prism 1995 GEO GEO- ABS #16213899"},
    };

    var to_search = new[] { "Geo", "JCB" };

    var result = from sr in list
                 let w = to_search.FirstOrDefault(ts => sr.Title.ToLower().Contains(ts.ToLower()))
                 where w != null
                 let a = new {sr=sr, word=w.ToLower()}
                 group a by a.word into g
                 orderby g.Count() descending
                 let sorted = g.OrderByDescending(a=> a.sr.Title.Select((c, i) => a.sr.Title.Substring(i)).Count(sub => sub.ToLower().StartsWith(a.word)))
                 from a in sorted 
                 select a.sr;

    var completeList = result.Concat(list.Except(result));

    foreach (var element in completeList)
        Debug.WriteLine(String.Format("ID={0},Title={1}", element.ID, element.Title));
}

输出:

ID=1,Title=Geo Prism 1995 GEO GEO- ABS #16213899
ID=2,Title=Geo Prism 1995 GEO - ABS #16213899
ID=3,Title=Geo Prism 1995 - ABS #16213899
ID=6,Title=JCB Excavator - ECU P/N: 728/35700
ID=4,Title=Wie man BBA reman erreicht
ID=5,Title=Ersatz Airbags, Gurtstrammer und Auto Körper Teile 

【讨论】:

  • 您的输出看起来不错。现在它正在工作。如果出现任何问题,我会在我的工作中实施后与您联系。非常感谢
  • 在执行你的查询后我很高兴,但是当我对大量数据执行查询时我变得非常失望,然后它不能完美地工作。当我搜索诸如“audi geo”之类的关键字时,大量的数据来自于 audi。结果以 audi 开头...没关系,但在 audi 记录结果应该假设以关键字 geo 开头但在 audi 其他记录显示之后,然后记录也带有 geo 和其他记录。所以我只是不明白为什么当列表有大量数据时这种行为很奇怪。如果你明白我想说什么,你能说清楚吗?谢谢
【解决方案2】:
    var result = (from searchResult in list
                 let title = searchResult.Title.ToLower()
                 let key_string = to_search.FirstOrDefault(ts => title.Contains(ts))
                 orderby key_string == null ? -1 : title.Split(new[] { key_string }, StringSplitOptions.None).Length descending
                 group searchResult by key_string into Group
                 select Group).OrderByDescending(grp => grp.Count()).ThenByDescending( grp => CountStringOccurrances(grp.Key, to_search));

public static int CountStringOccurrences(string text, string[] pattern)
{
    // Loop through all instances of the string 'text'.
    int count = 0;
    foreach (string itm in pattern)
    { 
       int i = 0;
       while ((i = text.IndexOf(itm, i)) != -1)
       {
          i += itm.Length;
          count++;
        }
    }
    return count;
}

【讨论】:

  • 嗯?他不希望它按标题排序。 Ersatz 出现在 Geo 之后。
  • 修复了新发现的阅读理解/理解问题。
  • 这一行给出错误。错误消息是“当前上下文中不存在组” OrderByDescending(group => group.Count()).ThenByDescending(CountStringOccurrences(group.Key, to_search));
  • 抱歉,group 是保留字。将“组”重命名为另一个名称。
猜你喜欢
  • 1970-01-01
  • 2010-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多