【问题标题】:LINQ - Preserve order across objects with .Any()? [duplicate]LINQ - 使用 .Any() 跨对象保留顺序? [复制]
【发布时间】:2013-06-25 19:52:04
【问题描述】:

我正在构建一个搜索功能,它需要返回一个按相关性排序的列表。

IList<ProjectDTO> projects = new List<ProjectDTO>();
projects = GetSomeProjects();

List<ProjectDTO> rawSearchResults = new List<ProjectDTO>();

//<snip> - do the various search functions here and write to the rawSearchResults

//now take the raw list of projects and group them into project number and 
//number of search returns.
//we will sort by number of search returns and then last updated date
var orderedProjects = rawSearchResults.GroupBy(x => x.ProjectNbr)
                                      .Select(x => new
                                      {
                                          Count = x.Count(),
                                          ProjectNbr = x.Key,
                                          LastUpdated = x.First().UpdatedDateTime
                                      })
                                      .OrderByDescending(x => x.Count)
                                      .ThenByDescending(x => x.LastUpdated);

到目前为止一切顺利; “orderedProjects”变量以正确的顺序返回我的列表。但是,下一步我需要整个对象。当我尝试查询以获取原始对象类型时,我的结果会丢失它们的顺序。回想起来,这是有道理的,但我需要找到解决方法。

projects = (from p in projects
            where orderedProjects.Any(o => o.ProjectNbr == p.ProjectNbr)
            select p).ToList();

是否有一种 LINQ 友好的方法来保留上述项目查询中的顺序?

我可以遍历orderedProject 列表并获取每个项目,但这不是很有效。我也可以在原始的 orderedProjects 查询中重建整个对象,但如果可能的话,我想避免这种情况。

【问题讨论】:

  • 您正在查看错误类型的解决方案。考虑如何从orderedProjects 中获取你想要的东西。
  • 不太确定你的问题...

标签: c# linq linq-to-objects


【解决方案1】:

你需要反过来做:
查询orderedProjects,从projects中选择对应的项:

var projects = 
    orderedProjects
        .Select(o => projects.SingleOrDefault(p => p.ProjectNbr == o.ProjectNbr))
        .Where(x => x != null) // This is only necessary if there can be
                               // ProjectNbrs in orderedProjects that are not in
                               // projects
        .ToList();

【讨论】:

  • 谢谢,效果很好。我试图反转查询,但无法让它工作——我觉得我做得太难了!
【解决方案2】:

您不应该在中间使用“Select”,因为该运算符会将对象转换为另一种类型,并且您说您需要原始对象。

var orderedProjects = rawSearchResults.GroupBy(x => x.ProjectNbr)                                      
                                  .OrderByDescending(x => x.Count)
                                  .ThenByDescending(x => x.First().UpdatedDateTime);

它们是按时间顺序排列的吗?否则,我很确定您希望在最新或最旧的项目更新上执行“ThenByDescending”,如下所示:

var orderedProjects = rawSearchResults.GroupBy(x => x.ProjectNbr)                                      
                                  .OrderByDescending(x => x.Count)
                                  .ThenByDescending(x => x.Max(p=>p.UpdatedDateTime));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-28
    • 1970-01-01
    • 1970-01-01
    • 2010-09-17
    • 1970-01-01
    相关资源
    最近更新 更多