我有一个简单的列表
var list =
AppUtils.db.GetDataTable("dbo.RankSelectChart", view) // stopred procedure and getting datatable
.AsEnumerable()
.Select(i => new
{
Date = i.Field<DateTime>("lastDatetime"),
P1 = i.Field<decimal>("p1"),
P2 = i.Field<decimal>("P2"),
P3..... P(n)
}
)
.ToList()
.OrderBy(x => x.Date);
比想要获取列表或字典列表List<Dictionary<Datetime, Decimal>>
表示Dictionary<Date, P1> .... Dictionary<Date, P(n)>
如何编写不依赖于我们有多少P的算法
答案 0 :(得分:1)
目前,您需要使用反射来访问属性:
var result = new[]{"P1", "P2", "P3", ...}.Select(p => list.ToDictionary(
i => i.Date,
i => i.GetType().GetProperty(p).GetValue(i)));
但是,如果您可以避免首先创建列表并直接从数据表中提取,则可能更容易。
var dt = AppUtils.db.GetDataTable("dbo.RankSelectChart", view); // stopred procedure and getting datatable
var pColumns = dt.Columns.Cast<DataColumn>()
.Where(c => c.ColumnName.StartsWith("p"));
var result = pColumns
.Select(p => dt.AsEnumerable().ToDictionary(
i => i.Field<DateTime>("lastDatetime"),
i => i.Field<DateTime>(p.ColumnName)))
.ToList();
答案 1 :(得分:1)
如果“日期”对于“列表”中的所有记录都是唯一的,那么您可以使用反射来获取列表中记录的P(i)值。像这样:
// build sample data
var list = Enumerable.Range(0, 10)
.ToList()
.Select(x => new {
Date = DateTime.Now.AddMinutes(x),
P1 = new Decimal(x),
P2 = new Decimal(x + 1),
P3 = new Decimal(x + 2)
})
.ToList();
// list partionned by date; assumes that Date is unique in list
List<Dictionary<DateTime, Decimal>> partitionedList;
if (list.Count == 0) {
partitionedList = new List<Dictionary<DateTime, Decimal>>();
} else {
var n = 3;
var listElementType = list[0].GetType();
partitionedList = Enumerable.Range(1, n)
.Select(x => {
var prop = listElementType.GetProperty("P" + x);
var pList = list.ToDictionary(
ll => ll.Date,
ll => (Decimal)prop.GetValue(ll));
return pList;
})
.ToList();
}
如果'Date'不是唯一的,那么它就不能成为字典的关键,并且无法实现所需的数据结构。