2016-09-19 92 views
0

我有一個數據集,它以C#中的對象列表形式出現,如下所示。C#根據時間戳合併多個列表

public class MotorDataModel 
    { 
     public DateTime timestamp { set; get; } 
     public decimal MotorSpeed { set; get; } 
     public decimal MotorTemp { set; get; } 
     public decimal MotorKw{ set; get; } 
    } 


public class MotorModel 
    { 
     public string MotorName { set; get; } 
     public List<MotorDataModel> MotorData { set; get; } 
    } 

當我做了查詢,我將有1條或多個MotorModel記錄回來(說電機1,2,3,...),每個都有自己的時間戳,並在這些時間不同的數據點郵票。

我然後發送這個數據給一個javascript圖表庫,它接受作爲數據表(例如像格式的電子表格)中的數據,如:

時間戳|電機1:kW | Motor1:速度| Motor1:Temp | Motor2:kW | Motor2:Speed ...

以及後面的行數據。數據將在時間戳上進行分組,該時間戳應該在幾分鐘之內以一致的增量(例如15分鐘)進行分組。該計劃是轉換C#中的數據,將其轉換爲JSON,並將其發送到圖表庫(Google Chart)。

我不必在C#中設置格式,並可以將C#中的對象列表數據轉換爲JSON,並在客戶端以JavaScript格式重新格式化它,但在服務器上轉換它似乎更好。

無論哪種方式,我都在努力如何將數據從多個對象列表轉換爲像數據表一樣的視圖。

This answer通過LINQ似乎很接近,但我有多個設備列表,而不是一個定義的數字。我也研究過循環和構建數據表(或數組),但不確定哪種結構最有意義。

所以,如果有人做了類似的事情,或有任何反饋,它將不勝感激。用於提供樣本數據

建議格式下面是由BlueMonkMN提供一些示例數據。請更新提供代表您實際問題的樣本數據的問題。

 List<MotorModel> allData = new List<MotorModel>() { 
     new MotorModel() {MotorName="Motor1", MotorData = new List<MotorDataModel> { 
      new MotorDataModel(){timestamp=new DateTime(2016, 9, 18, 2, 56, 0), MotorSpeed=20.0M, MotorTemp=66.2M, MotorKw=5.5M}, 
      new MotorDataModel(){timestamp=new DateTime(2016, 9, 18, 3, 10, 30), MotorSpeed=10.0M, MotorTemp=67.0M, MotorKw=5.5M}, 
      new MotorDataModel(){timestamp=new DateTime(2016, 9, 18, 3, 25, 45), MotorSpeed=17.5M, MotorTemp=66.1M, MotorKw=5.8M}, 
      new MotorDataModel(){timestamp=new DateTime(2016, 9, 18, 3, 40, 23), MotorSpeed=22.2M, MotorTemp=65.8M, MotorKw=5.4M} 
     }}, 
     new MotorModel() {MotorName="Motor2", MotorData = new List<MotorDataModel> { 
      new MotorDataModel(){timestamp=new DateTime(2016, 9, 18, 2, 58, 0), MotorSpeed=21.0M, MotorTemp=67.2M, MotorKw=5.6M}, 
      new MotorDataModel(){timestamp=new DateTime(2016, 9, 18, 3, 11, 30), MotorSpeed=11.0M, MotorTemp=68.0M, MotorKw=5.6M}, 
      new MotorDataModel(){timestamp=new DateTime(2016, 9, 18, 3, 24, 45), MotorSpeed=18.5M, MotorTemp=67.1M, MotorKw=5.9M}, 
      new MotorDataModel(){timestamp=new DateTime(2016, 9, 18, 3, 39, 23), MotorSpeed=23.2M, MotorTemp=66.8M, MotorKw=5.5M} 
     }} 
    }; 
+1

你的問題會更清晰,更易於回答和測試,如果您可以提供一小部分示例數據來演示您嘗試合併的實際數據的結構。例如,您是否有多個您試圖合併的List 實例? – BlueMonkMN

+0

你可以[編輯]你的問題來分享你想要的JSON輸出的例子嗎? – dbc

+0

BlueMonkMN,是的,謝謝,上面的數據示例運行良好。讓我通過下面的想法工作,我會回來的。謝謝! – user1644147

回答

0

一種可能性是遍歷所有數據,並按照您的建議構建表。我建議使用Dictionary,時間戳爲關鍵。對於每一個時間戳可以有多個MotorData的,所以它可能有一個列表,像這樣:

Dictionary<DateTime, List<MotorDataModel>> 

一段代碼,建立這個表是這樣的:

List<MotorModel> motorModels; // filled in previously 
// build result structure in this dictionary: 
Dictionary<DateTime, List<MotorDataModel>> table = new Dictionary<DateTime, List<MotorDataModel>>(); 
// iterate through all motors and their data, and fill in the table 
foreach(MotorModel m in motorModels) 
{ 
    foreach(MotorDataModel md in m.MotorData) 
    { 
     DateTime ts = md.timestamp; 
     // if this is the first occurance of the timestamp, create new 'row' 
     if (!table.ContainsKey(ts)) table[ts] = new List<MotorDataModel>(); 
     // add the data to the 'row' of this timestamp 
     table[ts].Add(md); 
    } 
} 

// output the table 
foreach(DateTime ts in table.Keys) 
{ 
    ... 
    foreach(MotorDataModel md in table[ts]) 
    { 
     ... 
    } 
} 
0

我會使用JSON來自NewtonSoft的.NET。

JObject o = new JObject(); 

foreach (MotorModel mm in allData) { 
    foreach (MotorDataModel mdm : mm.MotorData()) { 
     string key = mdm.TimeStamp.ToString(); // Or do your own format 
     o[key][mm.MotorName + ":kW"] = mdm.MotorKw; 
     o[key][mm.MotorName + ":Speed"] = mdm.MotorSpeed; 
     o[key][mm.MotorName + ":TEmp"] = mdm.MotorTemp; 
    } 
} 
0

你能嘗試這樣來計算您的數據:

var motorData = allData.SelectMany(x => x.MotorData).ToArray(); 
var starting = motorData.Min(x => x.timestamp); 
var ending = motorData.Max(x => x.timestamp); 
var duration = ending.Subtract(starting); 
var blocks = (int)Math.Ceiling(duration.TotalMinutes/15.0); 

var query = 
    from b in Enumerable.Range(0, blocks) 
    let s = starting.AddMinutes(b * 15.0) 
    let e = starting.AddMinutes((b + 1.0) * 15.0) 
    select new 
    { 
     Timestamp = s, 
     MotorSpeedAverage = 
      motorData 
       .Where(x => x.timestamp >= s && x.timestamp < e) 
       .Average(x => x.MotorSpeed), 
    }; 

我得到這樣的結果:

query