我想拍一个这样的物体:
SortedList<string, SortedList<int, SortedList<DateTime, double>>> Data
并且,对于给定的'int'值(第一个嵌套的排序列表的键),重构为:
SortedList<DateTime, SortedList<string, double>>
或者,更好的是,这个:
SortedList<DateTime, double[]>
其中每个'double []'包含的元素与SortedList中的KeyValue对一样多。
我猜Linq是要走的路,但无法弄清楚。感谢您的任何建议。
答案 0 :(得分:1)
digEmAll打败了我,但这是查询理解语法中的第二种情况:
int desiredInt = //whatever...
var query = from pair in Data
from pair2 in pair.Value
where pair2.Key == desiredInt
from pair3 in pair2.Value
group pair3.Value by pair3.Key into grp
select new { grp.Key, Value = grp.ToArray() };
var result = new SortedList<DateTime, double[]>(query.ToDictionary(a => a.Key, a => a.Value));
答案 1 :(得分:0)
第二种情况非常简洁:
var dateGroups = Data.SelectMany(x => x.Value)
.SelectMany(x => x.Value)
.GroupBy(x => x.Key)
.ToSortedList(g => g.Key,
g => g.Select(x => x.Value).ToArray());
第一种情况似乎错了,我怀疑它应该是:
SortedList<DateTime, SortedList<string, double[]>>
如果是这样,获得该代码的代码如下:
var dict =
(from x in Data
from y in x.Value
from z in y.Value
select new { StrKey = x.Key, IntKey = y.Key, DateKey = z.Key, Value = z.Value })
.GroupBy(x => x.DateKey)
.ToSortedList(g1 => g1.Key,
g1 => g1.GroupBy(x => x.StrKey)
.ToSortedList(g2 => g2.Key,
g2 => g2.Select(y => y.Value).ToArray()));
其中ToSortedList
是以下扩展名:
public static class Exts
{
public static SortedList<TK, TV> ToSortedList<TEl, TK, TV>(
this IEnumerable<TEl> elements,
Func<TEl, TK> keySelector,
Func<TEl, TV> valueSelector)
{
if(elements == null || keySelector == null || valueSelector == null)
throw new ArgumentNullException("An argument of ToSortedList is null");
var dict = new SortedList<TK, TV>();
foreach (var el in elements)
dict.Add(keySelector(el), valueSelector(el));
return dict;
}
}
答案 2 :(得分:0)
int givenKey = ...;
var variant1 = new SortedList<DateTime, SortedList<string, double>>(
Data.Select(pair => new { str = pair.Key, dateValues = pair.Value[givenKey] })
.Where(pair => pair.dateValues != null)
.SelectMany(pair => pair.dateValues.Select(dateValue => new { pair.str, date = dateValue.Key, value = dateValue.Value }))
.GroupBy(pair => pair.date)
.ToDictionary(group => group.Key, group => new SortedList<string, double>(group.ToDictionary(triple => triple.str, triple => triple.value)))
);
var variant2 = new SortedList<DateTime, double[]>(
Data.Select(pair => new { str = pair.Key, dateValues = pair.Value[givenKey] })
.Where(pair => pair.dateValues != null)
.SelectMany(pair => pair.dateValues.Select(dateValue => new { pair.str, date = dateValue.Key, value = dateValue.Value }))
.GroupBy(pair => pair.date)
.ToDictionary(group => group.Key, group => group.Select(triple => triple.value).ToArray())
);
答案 3 :(得分:0)
如果使用DateTime的完整分辨率,则无法进行转换,除非系统以某种方式规则化了插入的DateTime值。即使非常快速的插入也可能出现在不同的刻度上。如果你对它进行了规范化,那么你可以得到如下值:
Dictionary<DateTime, double[]> results = (from d1 in Data
from d2 in d1.Value
where d2.Key == 1
from d3 in d2.Value
group d3 by d3.Key into d3Group
select new {Key = d3Group.Key, Value = (from d4 in d3Group
select d4.Value).ToArray()
}).ToDictionary(element => element.Key, element => element.Value);
SortedList<DateTime, double[]> newSortedList = new SortedList<DateTime, double[]>(results);
答案 4 :(得分:0)
Phoog的答案很好,但也许你应该考虑ILookup
而不是SortedList
......
ILookup<DateTime, double> result =
(
from pair1 in Data
from pair2 in pair1.Value
where pair2.Key == givenInt
from pair3 in pair2.Value
from theDouble in pair3.Value
select new {theDateTime = pair3.Key, theDouble = theDouble }
)
.ToLookup(x => x.theDateTime, x => x.theDouble);