17

次のデータがあるとします。

時間 ステータス
10:00 オン
11:00 オフ
12:00 オフ
13:00 オフ
14:00 オフ
15:00 オン
16:00 オン

Linq を使用して次のようなものにグループ化するにはどうすればよいですか

[オン、[10:00]]、[オフ、[11:00、12:00、13:00、14:00]]、[オン、[15:00、16:00]]

4

5 に答える 5

12

ここGroupAdjacentにリストされているような拡張機能を作成します。

そして、それは次のように簡単です:

var groups = myData.GroupAdjacent(data => data.OnOffStatus);
于 2013-02-07T10:16:37.263 に答える
5

次のように、変数を使用して変更を追跡する 1 つの Linq クエリでこれを行うこともできます。

int key = 0;
var query = data.Select(
    (n,i) => i == 0 ? 
        new { Value = n, Key = key } : 
        new 
        { 
            Value = n, 
            Key = n.OnOffFlag == data[i - 1].OnOffFlag ? key : ++key 
        })
    .GroupBy(a => a.Key, a => a.Value);

基本的に、現在のアイテムが前のアイテムと等しくない場合に増加する各アイテムにキーを割り当てます。もちろん、これはデータがリストまたは配列にあることを前提としています。そうでない場合は、別の方法を試す必要があります

于 2013-02-07T13:55:01.153 に答える
4

これは、連続した要素を比較して連続したキーを生成するために使用するハードコアLINQ ソリューションです。Enumerable.Zip

var adj = 0;
var t = data.Zip(data.Skip(1).Concat(new TimeStatus[] { null }),
        (x, y) => new { x, key = (x == null || y == null || x.Status == y.Status) ? adj : adj++ }
    ).GroupBy(i => i.key, (k, g) => g.Select(e => e.x));
于 2013-02-07T13:42:49.960 に答える
3

それはとして行うことができます。

  1. コレクションを繰り返します。
  2. 使用TakeWhile<Predicate>条件は、コレクションの最初の要素のオンまたはオフのテキストです。
  3. ポイント1からのサブセットを繰り返し処理し、上記の手順を繰り返して文字列を連結します。

それが役に立てば幸い..

于 2013-02-07T10:27:49.167 に答える
1

クラスを定義するなど、リストを解析して連続したキーを割り当てることができます。

public class TimeStatus
{
    public int ContiguousKey { get; set; }
    public string Time { get; set; }
    public string Status { get; set; }
}

ループを繰り返し、カウントを維持し、ステータスがオンからオフに変化したことを検出するなどして、連続するキーに値を割り当てます。これにより、次のようなリストが得られます。

List<TimeStatus> timeStatuses = new List<TimeStatus> 
            {
                new TimeStatus { ContiguousKey = 1, Status = "On", Time = "10:00"},
                new TimeStatus { ContiguousKey = 1, Status = "On", Time = "11:00"},
                new TimeStatus { ContiguousKey = 2, Status = "Off", Time = "12:00"},
                new TimeStatus { ContiguousKey = 2, Status = "Off", Time = "13:00"},
                new TimeStatus { ContiguousKey = 2, Status = "Off", Time = "14:00"},
                new TimeStatus { ContiguousKey = 3, Status = "On", Time = "15:00"},
                new TimeStatus { ContiguousKey = 3, Status = "On", Time = "16:00"}
            };

次に、次のクエリを使用して、ステータスとグループ化された時間を抽出できます。

    var query = timeStatuses.GroupBy(t => t.ContiguousKey)
    .Select(g => new { Status = g.First().Status, Times = g });
于 2013-02-07T10:38:12.810 に答える