Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何按聚合进行分组?_C#_Linq_Group By_Overlapping - Fatal编程技术网

C# 如何按聚合进行分组?

C# 如何按聚合进行分组?,c#,linq,group-by,overlapping,C#,Linq,Group By,Overlapping,我有以下数据: ATMID StatusId ComponentId FromDateTime ToDateTime 4 1 3 2019-01-01 18:20 2019-01-01 18:45 4 2 5 2019-01-01 18:25 2019-01-01 18:45 5 3 2 2019

我有以下数据:

ATMID    StatusId  ComponentId   FromDateTime          ToDateTime
4           1          3        2019-01-01 18:20     2019-01-01 18:45
4           2          5        2019-01-01 18:25     2019-01-01 18:45
5           3          2        2019-01-01 18:10     2019-01-01 18:45 
5           1          2        2019-01-01 18:00     2019-01-01 18:45
5           6          5        2019-01-01 18:46     2019-01-01 18:50
我希望以这样一种方式进行汇总,其结果是:

Atmid    St_Comp         FromDateTime          ToDateTime
  4    {(1,3),(2,5)}    2019-01-01 18:20      2019-01-01 18:45 
  5    {(3,2),(1,2)}    2019-01-01 18:00      2019-01-01 18:45 
  5    {(6,5)}          2019-01-01 18:46      2019-01-01 18:50 
如何使用Linq实现这一点

这是我的密码:

var grouped = Problem_Fact_Measure_Overalls.GroupBy(
                  i => new { i.ATMId},
                  i => new {i.ComponentId,i.StatusId},
                  (Atmid, St_Comp) => new { Atmid, St_Comp });
但我无法在FromDateTime的最小值上进行聚合。

需要使用以下方法:

var result = data
    .Aggregate(
        new List<KeyValuePair<DateTimeRange, List<AtmRecord>>>(),
        (accumulator, atmRecord) => {
            var segment = accumulator.FirstOrDefault(
                v => atmRecord.ATMID == v.Value.First().ATMID && 
                    atmRecord.FromDateTime <= v.Key.To &&
                    atmRecord.ToDateTime >= v.Key.From);

            if (segment.Key == null)
            {
                accumulator.Add(new KeyValuePair<DateTimeRange, List<AtmRecord>>(
                    new DateTimeRange(atmRecord.FromDateTime, atmRecord.ToDateTime),
                    new List<AtmRecord>() {atmRecord}));

                return accumulator; 
            }

            if (atmRecord.FromDateTime < segment.Key.From)
            {
                segment.Key.From = atmRecord.FromDateTime;
            }

            if (atmRecord.ToDateTime > segment.Key.To)
            {
                segment.Key.To = atmRecord.ToDateTime;
            }                        

            segment.Value.Add(atmRecord);

            return accumulator;
        },
        accumulator => {
            return accumulator
                .Select(v => new 
                {
                    Atmid = v.Value.First().ATMID,
                    St_Comp = v.Value
                        .Select(r => (r.StatusId, r.ComponentId))
                        .ToArray(),
                    FromDateTime = v.Key.From,
                    ToDateTime = v.Key.To
                });
        })
        .ToArray();

/* result: 
[0]:{ Atmid = 4, St_Comp = {(int, int)[2]}, FromDateTime = {2019-01-01 6:20:00 p.m.}, ToDateTime = {2019-01-01 6:45:00 p.m.} }
Atmid [int]:4
FromDateTime [DateTime]:{2019-01-01 6:20:00 p.m.}
St_Comp:{(int, int)[2]}
[0]:(1, 3)
[1]:(2, 5)
ToDateTime [DateTime]:{2019-01-01 6:45:00 p.m.}

[1]:{ Atmid = 5, St_Comp = {(int, int)[2]}, FromDateTime = {2019-01-01 6:00:00 p.m.}, ToDateTime = {2019-01-01 6:45:00 p.m.} }
Atmid [int]:5
FromDateTime [DateTime]:{2019-01-01 6:00:00 p.m.}
St_Comp:{(int, int)[2]}
[0]:(3, 2)
[1]:(1, 2)
ToDateTime [DateTime]:{2019-01-01 6:45:00 p.m.}

[2]:{ Atmid = 5, St_Comp = {(int, int)[1]}, FromDateTime = {2019-01-01 6:46:00 p.m.}, ToDateTime = {2019-01-01 6:50:00 p.m.} }
Atmid [int]:5
FromDateTime [DateTime]:{2019-01-01 6:46:00 p.m.}
St_Comp:{(int, int)[1]}
[0]:(6, 5)
ToDateTime [DateTime]:{2019-01-01 6:50:00 p.m.}
 */
其他类别:

internal sealed class AtmRecord
{
    public int ATMID { get; }
    public int StatusId { get; }
    public int ComponentId { get; }
    public DateTime FromDateTime { get; }
    public DateTime ToDateTime { get; }

    public AtmRecord(int aTMID, int statusId, int componentId, DateTime fromDateTime, DateTime toDateTime)
    {
        ATMID = aTMID;
        StatusId = statusId;
        ComponentId = componentId;
        FromDateTime = fromDateTime;
        ToDateTime = toDateTime;
    }
}

internal sealed class DateTimeRange
{
    public DateTime From { get; set; }

    public DateTime To { get; set; }

    public DateTimeRange(DateTime from, DateTime to)
    {
        From = from;
        To = to;
    }
}

你想这样分组吗

var grouped = Problem_Fact_Measure_Overalls.GroupBy(r => r.ATMID)
.Select(g => new
{
    Atmid = g.Key,
    St_Comp = g.Select(r => (r.StatusId, r.ComponentId)).ToArray(),
    FromDateTime = g.Min(r => r.FromDateTime),
    ToDateTime = g.Max(r => r.ToDateTime)
});
输出:

4   (1, 3), (2, 5)           2019-01-01 18:20   2019-01-01 18:45
5   (3, 2), (1, 2), (6, 5)   2019-01-01 18:00   2019-01-01 18:50

那么,你想把它们分成两(对)组?你尝试了什么?这不仅仅是严格的分组,你有两行用于Atmid=5。我猜这是因为最后一个的fromDate>ToDate?请用你已经做过的努力完整地说明你的问题。为什么要重叠标签?基于这一点输入很难获得你需求的参数。请更具体地说明你想要实现什么,你已经尝试了什么,以及你在哪里遇到了困难。现在它的意思是“请为我做这件事”。
4   (1, 3), (2, 5)           2019-01-01 18:20   2019-01-01 18:45
5   (3, 2), (1, 2), (6, 5)   2019-01-01 18:00   2019-01-01 18:50