|
- using Newtonsoft.Json;
- using System.Reflection;
- using System.Text.RegularExpressions;
-
- namespace HealthMonitor.Model.Service.Mapper
- {
- public class ParseTDengineRestResponse<T>
- {
- #region 泛化解析
- private List<T> ParseDataList(dynamic data)
- {
- List<T> result = new();
-
- foreach (var row in data)
- {
- var model = CreateInstance<T>();
-
- for (int i = 0; i < ColumnMeta.Count; i++)
- {
- var columnName = ColumnMeta[i][0].ToString()!;
- var columnType = ColumnMeta[i][1].ToString()!;
-
- string pattern = @"\((.*?)\)"; // 匹配括号内的任意字符(非贪婪模式)
-
- // 使用正则表达式进行匹配
- Match match = Regex.Match(columnName, pattern);
-
- // 检查是否有匹配项
- if (match.Success)
- {
- // 提取括号内的内容
- string contentInsideParentheses = match.Groups[1].Value;
- columnName = contentInsideParentheses;
- }
-
- var columnValue = ConvertValue(row[i], columnType!);
-
- SetProperty(model, columnName!, columnValue);
- }
-
- result.Add(model);
- }
-
- return result;
- }
-
- private static T CreateInstance<U>()
- {
- return Activator.CreateInstance<T>();
- }
-
- private static void SetProperty<TValue>(T target, string propertyName, TValue value)
- {
- var property = typeof(T).GetProperties()
- .FirstOrDefault(p => GetJsonPropertyName(p) == propertyName);
-
- if (property != null)
- {
- property.SetValue(target, value);
- }
- }
-
- private static object ConvertValue(object value, string columnType)
- {
- return columnType.ToUpper() switch
- {
- "TIMESTAMP" => DateTime.TryParse(value.ToString(),out DateTime dateTimeValue)? dateTimeValue:DateTime.Now,
- "NCHAR" or "VARCHAR" => value==null?string.Empty:value.ToString()!,
- "INT" => int.TryParse(value.ToString(), out int intValue)? intValue:0,
- "TINYINT" => Convert.ToByte(value),
- "BOOL" => Convert.ToBoolean(value),
- "FLOAT" => float.TryParse(value.ToString(), out float floatValue)? floatValue : 0f,
- _ => value,
- } ;
-
- }
-
- private static string GetJsonPropertyName(PropertyInfo property)
- {
- var attribute = (JsonPropertyAttribute)Attribute.GetCustomAttribute(property, typeof(JsonPropertyAttribute))!;
- return attribute?.PropertyName ?? property.Name;
- }
-
- private List<T> ParseData = default!;
- #endregion
-
- #region 响应解析
- [JsonProperty("code")]
- public int Code { get; set; }
-
- [JsonProperty("column_meta")]
- public List<List<object>> ColumnMeta { get; set; } = new List<List<object>>();
-
- [JsonProperty("rows")]
- public int Rows { get; set; }
-
- [JsonProperty("data")]
- public dynamic Data
- {
- get => ParseData;
- set => ParseData = ParseDataList(value);
- }
-
- #endregion
-
- #region Linq
- public IEnumerable<TResult> Select<TResult>(Func<T, TResult> selector)
- {
- return ParseData.Select(selector);
- }
-
- public IEnumerable<T> Select()
- {
- return ParseData;
- }
- #endregion
-
- #region 统计算法
- /// <summary>
- /// 统计算法
- /// </summary>
- /// <param name="valueSelector"></param>
- /// <param name="numToRemove"></param>
- /// <returns></returns>
- /// <exception cref="ArgumentException"></exception>
- public float AverageAfterRemovingOneMinMaxRef(Func<T, float> valueSelector, int numToRemove, out int[] collection, out int max, out int min)
- {
- var values = ParseData.Select(valueSelector).ToList();
- collection = values.Select(i => (int)i).ToArray();
- if (values.Count <= 2)
- {
- throw new ArgumentException("Not enough elements to remove.");
- }
-
- // Remove the specified number of minimum and maximum values
- //values.RemoveAll(_ => _ == values.Min());
- //values.RemoveAll(_ => _ == values.Max());
- max = (int)values.Max();
- min = (int)values.Min();
- values.Remove(max);
- values.Remove(min);
-
- // Remove values less than the specified threshold
- values.RemoveAll(_ => _ > numToRemove);
-
- // Calculate and return the average of the remaining values
- return values.Average();
- }
-
- public decimal AverageAfterRemovingOneMinMaxRef(Func<T, decimal> valueSelector, int refValue)
- {
- var values = ParseData.Select(valueSelector).ToList();
- // Remove the specified number of minimum and maximum values
- //values.RemoveAll(_ => _ == values.Min());
- //values.RemoveAll(_ => _ == values.Max());
-
- values.Remove(values.Max());
- values.Remove(values.Min());
-
- // Remove values less than the specified threshold
- values.RemoveAll(_ => _ > refValue);
-
- if (values.Count < 2)
- {
- // throw new ArgumentException("数据不够不能计算");
- // 平均值为0,说明数据不足,不能计算增量值
- return 0M;
- }
- // Calculate and return the average of the remaining values
- return values.Average();
- }
-
- #endregion
-
- }
- }
|