I want to group my data based on a given time interval like 1m, 1h, 1d etc..
var tables = await query.QueryAsync(flux, "AAE");
return tables.SelectMany(table =>
table.Records.Select(record =>
new MachineDataModel
{
result = record.GetValueByKey("result").ToString(),
table = int.Parse(record.GetValueByKey("table").ToString()),
_start = record.GetValueByKey("_start").ToString(),
_stop = record.GetValueByKey("_stop").ToString(),
_time = record.GetValueByKey("_time").ToString(),
_value = int.Parse(record.GetValueByKey("_value").ToString()),
_field = record.GetValueByKey("_field").ToString(),
_measurement = record.GetValueByKey("_measurement").ToString(),
end_time_str = record.GetValueByKey("end_time_str").ToString(),
machine = record.GetValueByKey("machine").ToString(),
start_time_str = record.GetValueByKey("start_time_str").ToString(),
}));
});
returnModel.MachineList = results.ToList();
I want to group the data that is in the returnModel.MachineList by a given interval. I have no idea how to do this.
CodePudding user response:
Since you haven't provided the data model, I assumed...
class MachineDataModel
{
public DateTime _start; //can also be parsed from '_start_time_str'
public DateTime _end; //can also be parsed from '_end_time_str'
//..some more....
}
You can Group Elements by a minute interval with:
var GroupByMinutesList = list.GroupBy(x => (x._end - x._start).Minutes);
//replace 'Minutes' with 'Hours', 'Days', etc...
To convert it to a dictionary simply:
var GroupedByMinutesDictionary = GroupByMinutesList.ToDictionary(x => x.Key.ToString() " minute(s)", x => x.ToList());
the above dictionary will give you:
{
"1 minute(s)":
{
myMachineDataModel object
},
"2 minute(s)":
{
myMachineDataModel object
}
etc...
}
The Test Data I used
List<MachineDataModel> list = new()
{
new MachineDataModel
{
_start = DateTime.Now,
_end = DateTime.Now.AddSeconds(30)
},
new MachineDataModel
{
_start = DateTime.Now,
_end = DateTime.Now.AddSeconds(90)
},
new MachineDataModel
{
_start = DateTime.Now,
_end = DateTime.Now.AddSeconds(45)
},
new MachineDataModel
{
_start = DateTime.Now,
_end = DateTime.Now.AddSeconds(75)
}
};
Result:
//JsonConvert.SerializeObject(GroupedByMinutesDictionary)
{
"0 minute(s)": [
{
"_start": "2022-01-19T10:47:03.2527701 05:00",
"_end": "2022-01-19T10:47:33.2527733 05:00"
},
{
"_start": "2022-01-19T10:47:03.2528154 05:00",
"_end": "2022-01-19T10:47:48.2528156 05:00"
}
],
"1 minute(s)": [
{
"_start": "2022-01-19T10:47:03.2528141 05:00",
"_end": "2022-01-19T10:48:33.2528145 05:00"
},
{
"_start": "2022-01-19T10:47:03.2528158 05:00",
"_end": "2022-01-19T10:48:18.252816 05:00"
}
]
}
CodePudding user response:
Assuming you can parse your _time string to a DateTime, you can use GroupBy like so:
Func<DateTime, long> GetIntervalKeyGenerator(Interval interval)
=> interval switch
{
Interval.Years => date => date.Year,
Interval.Days => date => date.Year * 1000 date.DayOfYear,
...
_ => throw new NotImplementedException()
};
Enumerable.Range(1, 1000)
.Select(i => DateTime.Now TimeSpan.FromMinutes(i))
.GroupBy(GetIntervalKeyGenerator(Interval.Hours), date => date);
