Поворот коллекции массивов - PullRequest
2 голосов
/ 10 сентября 2010

По сути, у меня есть коллекция объектов, каждый из которых реализует член типа 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}} Тем не менее, я думаю, что есть более приятное, стройное и читаемое выражение для этого. Может ли кто-нибудь указать мне правильное направление?

1012 * редактировать * информация о базовых классах

    interface IValueCollection : IEnumerable<decimal>

    class MeasurementCollection : ICollection<IMeasurement>

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

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

1 Ответ

2 голосов
/ 10 сентября 2010

Я бы лично форсировал оценку вашей коллекции и использовал ее как массив. Прямо сейчас, каждый раз, когда вы звоните 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...
}
...