获取每个项目的最大值通用列表

时间:2012-09-13 10:27:23

标签: c# linq

我想知道你是否可以提供帮助。

我有一份信息清单;

ClientNo SequenceNo

这可能包含诸如

之类的数据

Cli No:0000001,seq:1
Cli No:0000001,seq:2
Cli No:0000001,seq:3
Cli No:0000001,seq:3
Cli No:0000002,seq:1
Cli No:0000002,seq:1
Cli No:0000002,seq:2
Cli No:0000002,seq:2

我想生成一个最大序列号列表。

请注意,序列号可以重复多次,如上例所示。

因此,我想从示例中得到的列表将是;

Cli No:0000001,seq:3
Cli No:0000001,seq:3
Cli No:0000002,seq:2
Cli No:0000002,seq:2

我试过了;

  var x = criticalNotesData.OrderBy(y => y.ClientNo)
         .ThenBy(z => z.SequenceNo).ToList();
  var m = x.Max(r => r.SequenceNo).ToList();

但最大值只是在列表中提供最大序列号,而不是每个客户端。

谢谢,

大卫

6 个答案:

答案 0 :(得分:3)

使用GroupBy 两次然后OrderByDescending获取First而不是Max,这样就不需要< em>创建新对象并仍然获取重复的最大项

var result = criticalNotesData.GroupBy(x => x.ClientNo)
                              .SelectMany(g => g.GroupBy(y => y.SequenceNo)
                                                .OrderByDescending(gg => gg.Key)
                                                .First()
                                           );

结果将完全符合您的要求:

Cli No: 0000001, seq: 3 
Cli No: 0000001, seq: 3 
Cli No: 0000002, seq: 2 
Cli No: 0000002, seq: 2 

答案 1 :(得分:1)

你需要GroupBy

var maxItems = criticalNotesData.GroupBy(p => p.ClientNo)
                                .Select(r => r.Max(q => q.SeqNo));
像这样的东西。

var maxItemsClientWise = from p in criticalNotesData
                           group p by p.ClientNo into r
                           select new { MaxSeq = r.Max(g => g.SeqNo), 
                                        Client = r.First().ClientNo };

答案 2 :(得分:1)

我不能尝试,但我认为这应该有效!

var m = x.GroupBy(r => r.ClientNo).Select(g => g.Max(x => x.SequenceNo));

编辑:了解客户:

var m = x.GroupBy(r => r.ClientNo).Select(g => new { ClientID = g.Key, Max = g.Max(x => x.SequenceNo) });

答案 3 :(得分:1)

您可以使用以下查询根据您的条件获取类对象的列表。

var query = (from t in list
            group t by t.CliNo into tgroup
            select new ClientSequence
            {
                CliNo = tgroup.Key,
                seq = tgroup.Max(r => r.seq)

            }).ToList();

假设你的班级结构是:

class ClientSequence
{
    public string CliNo { get; set; }
    public int seq { get; set; }
}

,你的清单是:

List<ClientSequence> list = new List<ClientSequence>
       {
           new ClientSequence{ CliNo= "0000001", seq= 1},
           new ClientSequence{ CliNo= "0000001", seq= 2},
           new ClientSequence{ CliNo= "0000001", seq= 3},
           new ClientSequence{ CliNo= "0000002", seq= 1},
           new ClientSequence{ CliNo= "0000002", seq= 1},
           new ClientSequence{ CliNo= "0000002", seq= 1},
           new ClientSequence{ CliNo= "0000002", seq= 2},
           new ClientSequence{ CliNo= "0000002", seq= 2},
   };

输出:

foreach (ClientSequence cs in query)
{
    Console.Write("Client No.: " + cs.CliNo);
    Console.WriteLine(" Max Sequence No.: " + cs.seq);
}

会打印

Client No.: 0000001 Max Sequence No.: 3
Client No.: 0000002 Max Sequence No.: 2

答案 4 :(得分:0)

您希望每个“客户”条目都知道最高序列。因此,这意味着结果应该是一个序列(每个客户端)而不是Max返回的单个值。怎么样:

var maxSequence = criticalNotesData
      .GroupBy(n => n.ClientNo)
      .Select(g => new { Client = g.Key, Max = g.Max(i => i.SequenceNo) } );

foreach ( var entry in maxSequence )
{
    Console.WriteLine("Client {0} has max sequence of {1}", 
                      entry.Client, entry.Max); 
}

// Looking at your original, you now want only to know the (from the original)
// the entries matching MAX.  Since you now know the max per client, a second
// operation is needed.
var maxValueEntries = criticalNotesData
        .Where(n => maxSequence
                      .Single(c => c.Client == n.Client)
                      .Max == n.SequenceNo));

maxValueEntries正在进行大量的查找,因此值列表可能会更好。

// Turning the original into a Dictionary of clientNo returning the 
// max sequence.
var maxSequence2 = criticalNotesData
      .GroupBy(n => n.ClientNo)
      .Select(g => new { Client = g.Key, Max = g.Max(i => i.SequenceNo) } )
      .ToDictionary(c => c.Client, c => c.Max);
var maxValueEntries2 = criticalNotesData
        .Where(n => maxSequence2[n.Client] == n.SequenceNo));

答案 5 :(得分:0)

假设这样的数据:

var list = new []
{
    new { CliNo= "0000001", SeqNo= 1 },
    new { CliNo= "0000001", SeqNo= 2 },
    new { CliNo= "0000002", SeqNo= 1 },     
    new { CliNo= "0000001", SeqNo= 3 },
    new { CliNo= "0000001", SeqNo= 3 },
    new { CliNo= "0000002", SeqNo= 1 },
    new { CliNo= "0000002", SeqNo= 1 },
    new { CliNo= "0000002", SeqNo= 2 },
    new { CliNo= "0000002", SeqNo= 2 },
};

你可以用这个:

var output = 
    from i in list
    orderby i.CliNo, i.SeqNo
    group i by i.CliNo into g
    let max = g.Max(x => x.SeqNo)
    from r in g where r.SeqNo == max
    select r;

我在评论中说的仍然有效,数据的初始顺序很重要,在这段代码中我采用了一般方法,但如果你对初始订单有保证,那么还有其他策略可以提高效率你的数据来源很昂贵。