2012-03-27 46 views
0

我想採取這樣的對象:重組對象

SortedList<string, SortedList<int, SortedList<DateTime, double>>> Data 

,並且對於給定的「INT」值(第一嵌套排序列表的鍵),重組這樣的:

SortedList<DateTime, SortedList<string, double>> 

,或者更好的是,這樣的:

SortedList<DateTime, double[]> 

,其中每個「雙[]」具有一樣多的元素有鍵值對在排序列表。

我猜Linq是要走的路,但無法弄清楚。感謝您的任何建議。

+2

請不要用C#前言或LINQ,這是標籤的用途。 – 2012-03-27 17:28:42

+0

您的頂級列表是否可以包含多個包含相同'int'作爲關鍵字的鍵值對? – dasblinkenlight 2012-03-27 17:30:24

+0

如果您使用DateTime的完整分辨率,則不能進行轉換,除非系統以某種方式調整插入的DateTime值。即使非常快速的插入也可能發生在不同的刻度上。 – JamieSee 2012-03-27 17:36:37

回答

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)); 
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; 
    } 
} 
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()) 
); 
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); 
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);