2012-09-13 97 views
1

我想知道您是否可以提供帮助。获取最大值每个项目的通用列表

我有一个信息列表;

ClientNo SequenceNo

这可能包含诸如数据;

Cli时号:0000001,SEQ ID NO:1
Cli时号:0000001,SEQ ID NO:2
Cli时号:0000001,SEQ ID NO:3
Cli时号:0000001,SEQ ID NO:3
Cli时号:0000002,SEQ :1
CLI的编号:0000002,序列:1
CLI的编号:0000002,SEQ:2
CLI的编号:0000002,SEQ:2

我想产生的最大序列号的列表。

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

因此,我想从例子中结束的列表是;

CLI的编号:0000001,SEQ:3
CLI的编号:0000001,SEQ:3
CLI的编号:0000002,SEQ:2
CLI的编号:0000002,SEQ:2

我曾尝试;

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

感谢,

大卫

+1

与重复的客户号码有什么关系?你想要的输出背后的逻辑是什么? – Jon

+0

为什么你需要重复的条目? – sll

+0

序列的每一行还有一个名为“行号”的字段,另一行称为“文本”。所以我需要最高的序列号,然后结合所有连接到该序列的文本行,但是我可以做到这一点,只需要获得每个客户端的最高序列号。 –

回答

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 
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 }; 
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) }); 
+0

枚举'm'时,你不知道它引用了哪个客户端。 –

+0

这很容易编辑... :) – Alessandro

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)); 
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 
+0

你好,谢谢,如果我的班级结构是 公共类KNOWTXTS:ExcelReport { public String ClientNo {get;组; } public String TextType {get;组; } public String SequenceNo {get;组; } public String LineNo {get;组; } public String Text {get;组; } } 我还需要将其他字段添加到查询中? –

+0

@DavidJohnson,只有当你返回你的类对象列表时,否则你可以返回任何匿名对象并使用它 – Habib

+0

好的,谢谢你的帮助! –

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; 

仍然是有效的我在评论说,该数据的初始顺序是非常重要的,在此代码我采取了一种通用的方法,但如果您对最初的订单有保证,那么如果您的数据来源昂贵,还有其他策略可以更高效。

相关问题