1

我想知道你能不能帮忙。

我有一份信息清单;

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 号:0000001,seq:3 Cli 号:0000001,seq
:3
Cli 号:0000002,seq:2
Cli 号:0000002,seq:2

我试过了;

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

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

谢谢,

大卫

4

6 回答 6

3

使用GroupBy 两次然后OrderByDescending获取First而不是使用Max,通过这种方式,您不需要创建新对象并且仍然可以获得重复的最大项目

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 
于 2012-09-13T10:59:04.477 回答
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 };
于 2012-09-13T10:32:11.870 回答
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) });
于 2012-09-13T10:32:34.967 回答
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
于 2012-09-13T10:41:44.540 回答
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));
于 2012-09-13T10:34:14.270 回答
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;

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

于 2012-09-13T22:04:02.413 回答