2010-09-10 2 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... 
} 
Смежные вопросы