2010-09-10 51 views
2

的集合基本上我有對象的集合各自實現類型IValueCollection的成員樞轉陣列

public interface IValueCollection : IEnumerable<decimal> 
{ 
    decimal this[int index] { get; set; } 
} 

MeasurementCollection.Values是類型IValueCollection的。

用下面的邏輯我想旋轉一個IValueCollection的集合,並寫下面的擴展方法。

public static IEnumerable<IValueCollection> PivotValues(this MeasurementCollection items) 
    { 
     if(items.IsQuantized()) 
     { 
      int s = (int)items.First().Template.Frequency; // 
      int c = items.Count; 
      for (int n = 0; n < s; n++) 
      { 
       IValueCollection v = new MeasurementValueCollection(c); 
       for (int m = 0; m < c; m++) 
       { 
        v[m] = items.ElementAt(m).Values[n]; 
       } 
       yield return v; 
      } 
     } 
    } 

應該做 {{1,2,3} {4,5,6} {7,8,9}}結果{{1,4,7},{2,5,8 },{3,6,9}} 但是我認爲有一些更好,更苗條和更具可讀性的表達方式可以讓別人指向正確的方向嗎?關於底層階級

interface IValueCollection : IEnumerable<decimal> 

    class MeasurementCollection : ICollection<IMeasurement> 

    interface IMeasurement 
    { 
     IMeasurementTemplate Template { get; }   
     ...... 
    } 

    interface IMeasurementTemplate 
    { 
     ..... 
     MeasurementFrequency Frequency { get; }  
    } 

回答

2

我個人而言,強制提前您的收藏的評價,並把它作爲一個數組

編輯 信息。現在,每次您撥打ElementAt時,您將再次評估IEnumerable<T>,導致大量重複搜索。

通過強制它預先評估一個數組,可以簡化整個過程。喜歡的東西:

public static IEnumerable<IValueCollection> PivotValues(this MeasurementCollection items) 
{ 
    if(items.IsQuantized()) 
    { 
     int elementLength = (int)items.First().Template.Frequency; 
     var itemArray = items.ToArray(); 
     for (int n = 0; n < itemArray.Length; n++) 
     { 
      IValueCollection v = new MeasurementValueCollection(elementLength); 
      for (int m = 0; m < elementLength; m++) 
      { 
       v[m] = itemArray[m].Values[n]; 
      } 
      yield return v; 
     } 
    } 
    else 
     yield break; // Handle the case where IsQuantized() returns false... 
} 

如果你控制MeasurementValueCollection,我想補充一個構造函數,需要一個IEnumerable<decimal>作爲輸入,以及。你可以這樣做:

public static IEnumerable<IValueCollection> PivotValues(this MeasurementCollection items) 
{ 
    if(items.IsQuantized()) 
    { 
     var elements = Enumerable.Range(0, (int)items.First().Template.Frequency); 
     var itemArray = items.ToArray(); 

     foreach(var element in elements) 
      yield return new MeasurementValueCollection(
           itemArray.Select( 
            (item,index) => itemArray[index].Value[element] 
           ) 
          ); 
    } 
    else 
     yield break; // Handle the case where IsQuantized() returns false... 
}