3

だから、私はこのようなリストを持っています。基本的には、一連のアイテムの状態履歴であり、最新の状態が現在の状態を表します。

Record   Id      State       Date
=====    ===     =========  =======
1        A       Waiting     Jan 01
2        A       InProgress  Jan 02
3        A       Finished    Jan 03
4        B       Waiting     Jan 02
5        C       Waiting     Jan 01
6        C       InProgress  Jan 02
7        D       Waiting     Jan 01
8        D       InProgress  Jan 02

私が探しているのは、各アイテムの「現在の」状態を照会できるようにすることです。たとえば、「すべての Id が 'InProgress' であることを教えてください」と言い、Id D と Id C を取得しますが、Id A は取得しません (最新の状態が 'Finished' であるため)。

グループ化と順序付けまたはマキシングを行う必要があることはわかっていますが、すべてをまとめることはできません。

4

3 に答える 3

9
myList.GroupBy(m => m.Id)
.Select(g => g.OrderByDescending(x => x.Date).First())
.Where(<your filter>);
于 2013-05-29T14:05:22.247 に答える
2

ここにあなたが望むことをするためのいくつかのコードがあります。各 ID の最新の状態を取得し、完了したレコードを無視します。実行できる完全な動作例を提供しました (実際のデータで動作するように適応できることを願っています)。

//the example data provided by the OP
var data = new []
{
    new { Record = 1, Id = "A", State = "Waiting", Date = new DateTime(2013, 1, 1) },
    new { Record = 2, Id = "A", State = "InProgress", Date = new DateTime(2013, 1, 2) },
    new { Record = 3, Id = "A", State = "Finished", Date = new DateTime(2013, 1, 3) },        
    new { Record = 4, Id = "B", State = "Waiting", Date = new DateTime(2013, 1, 1) },        
    new { Record = 5, Id = "C", State = "Waiting", Date = new DateTime(2013, 1, 1) },
    new { Record = 6, Id = "C", State = "InProgress", Date = new DateTime(2013, 1, 2) },        
    new { Record = 7, Id = "D", State = "Waiting", Date = new DateTime(2013, 1, 1) },
    new { Record = 8, Id = "D", State = "InProgress", Date = new DateTime(2013, 1, 2) },
};

var query = from d in data
            //put the newest record first
            orderby d.Date descending
            //group by the id
            group d by d.Id into groupedById
            //get the latest record for each id
            let latest = groupedById.First()
            //filter out finished records
            where latest.State != "Finished"
            select latest;

そして、これがLinqPadからの出力です。

ここに画像の説明を入力

終了したために無視された「A」を除いて、各アイテムの最新の状態があることがわかります。

于 2013-05-29T14:21:52.680 に答える
1

これが LINQ to Objects の場合 (レコードが正しい順序で配置されていると仮定)、次のことができます。

var latestById = records.GroupBy(record => record.Id)
                        .ToDictionary(group => group.Key, group => group.Last());

これは、GroupByが「グループ内の要素は、ソースに表示される順序で生成される」ことを保証するためです。

レコードの順序について保証できない場合は、次のようにします。

var latestById = records.GroupBy(record => record.Id)
                        .Select(group => group.MaxBy(r => r.Date))
                        .ToDictionary(record => record.Id);

ここでMaxByはmoreLinqから来ています。

ちなみに、これが LINQ to SQL の場合、次のようにします。

var latestById = records.GroupBy(record => record.Id)
                        .Select(group => group.OrderByDescending(r => r.Date).First())
                        .AsEnumerable()
                        .ToDictionary(record => record.Id);
于 2013-05-29T14:05:56.767 に答える