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... 
}