使用LINQ在组分区内订购集合

时间:2012-04-06 14:54:28

标签: c# linq

我有简单类型Question

public class Question
{
    public string[] Tags { get; set; }
    public DateTime Created { get; set; }
}

虽然我有一个问题列表,但我需要沿着标签列表(称为过滤器)过滤它们。具有最多标签的过滤器列表匹配的问题应该放在结果集合中更高的位置。我为此写了表达式:

public IList<Question> GetSimiliar(IList<Questions> all, string[] filters)
{
    var questions = all.Select(
                        x => new 
                               { 
                                  MatchedTags = x.Tags
                                                 .Count(tag => filters.Contains(tag)), 
                                  Question = x 
                               })
                       .Where(x => x.MatchedTags > 0)
                       .OrderByDescending(x => x.MatchedTags)
                       .Select(x => x.Question);

    return questions.ToList();
}

现在我需要支持这种情况,我有多个匹配标签数量相同的问题。此类问题应按创建日期(从最新到最旧)进一步排序。

我想要的例子:

filter:tags = [a,b,c]

要过滤的问题集合:

  1. q1 {tags = [a],created = 1939}
  2. q2 {tags = [b],created = 1945}
  3. q3 {tags = [a,b,c],created = 1800}
  4. q4 {tags = [a,b],created = 2012}
  5. q5 {tags = [z],created = 1999}
  6. 结果 - 已排序的集合:

    1. Q3
    2. Q4
    3. Q2
    4. Q1
    5. 如何使用linq做到这一点?

2 个答案:

答案 0 :(得分:3)

  

现在我需要支持这种情况,我有多个匹配标签数量相同的问题。此类问题应按创建日期(从最新到最旧)进一步排序

使用ThenByThenByDescending进一步对查询进行排序。在先前的订购中使用这些方法来打破关系。

.OrderByDescending(x => x.MatchedTags)
.ThenByDescending(x => x.Question.Created)
.Select(x => x.Question); 

答案 1 :(得分:1)

101 Linq Samples page有一个nested grouping example。此示例使用group by来分区每个客户订单的列表,首先按年,然后按月划分:

public void Linq43() 
{ 
    List<Customer> customers = GetCustomerList(); 

    var customerOrderGroups = 
        from c in customers 
        select 
            new 
            { 
                c.CompanyName, 
                YearGroups = 
                    from o in c.Orders 
                    group o by o.OrderDate.Year into yg 
                    select 
                        new 
                        { 
                            Year = yg.Key, 
                            MonthGroups = 
                                from o in yg 
                                group o by o.OrderDate.Month into mg 
                                select new { Month = mg.Key, Orders = mg } 
                        } 
            }; 

    ObjectDumper.Write(customerOrderGroups, 3); 
}