旋转阵列的集合 [英] Pivoting a collection of arrays

查看:152
本文介绍了旋转阵列的集合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

基本上我有对象的集合各自实现类型IValueCollection成员

  public接口IValueCollection:IEnumerable的<&小数GT;
{
    十进制这个[INT指数] {搞定;组; }
}

MeasurementCollection.Values​​的类型是IValueCollection的。

通过逻辑下面我想转动IValueCollection的集合,并写下面的扩展方法。

 公共静态的IEnumerable< IValueCollection> PivotValues​​(这MeasurementCollection项)
    {
        如果(items.IsQuantized())
        {
            INT S =(int)的items.First()Template.Frequency。 //
            INT C = items.Count;
            对于(INT N = 0; N< S; N ++)
            {
                IValueCollection V =新MeasurementValueCollection(C);
                为(中间体m = 0时,M c为C; M +)
                {
                    v [米] = items.ElementAt(米).Values​​ [n]的;
                }
                产生回报伏;
            }
        }
    }

应该做的
{{1,2,3} {4,5,6} {7,8,9}}的结果{{1,4,7},{2,5,8},{3,6,9}}
不过,我认为有一些更好,更轻薄,更具可读性前pression做到这一点
可有人点我在正确的方向?

修改
关于底层阶级资讯

 接口IValueCollection:IEnumerable的<&小数GT;    类MeasurementCollection:ICollection的< IMeasurement>    接口IMeasurement
    {
        IMeasurementTemplate模板{搞定; }
        ......
    }    接口IMeasurementTemplate
    {
        .....
        MeasurementFrequency频率{搞定; }
    }


解决方案

我个人而言,强制提前您的收藏的评价,并把它作为一个数组。现在,每次调用 ElementAt的,你要评估在的IEnumerable< T> 再次,造成大量重复搜索的

,迫使它来评估一个数组提前,可以简化整个过程。是这样的:

 公共静态的IEnumerable< IValueCollection> PivotValues​​(这MeasurementCollection项)
{
    如果(items.IsQuantized())
    {
        INT elementLength =(int)的items.First()Template.Frequency。
        变种itemArray = items.ToArray();
        对于(INT N = 0; N< itemArray.Length; N ++)
        {
            IValueCollection V =新MeasurementValueCollection(elementLength);
            对于(INT M = 0; M< elementLength; M +)
            {
                v [米] = itemArray [米] .Values​​ [n]的;
            }
            产生回报伏;
        }
    }
    其他
        产生中断; //处理,其中IsQuantized()返回false的情况下...
}

如果你控制 MeasurementValueCollection ,我想补充一个构造函数,需要一个的IEnumerable<十进制> 作为输入,就好。然后,你可以这样做:

 公共静态的IEnumerable< IValueCollection> PivotValues​​(这MeasurementCollection项)
{
    如果(items.IsQuantized())
    {
        无功元件= Enumerable.Range(0,(int)的items.First()Template.Frequency);
        变种itemArray = items.ToArray();        的foreach(以元素变种元素)
            产量返回新MeasurementValueCollection(
                                 itemArray.Select(
                                   (项指数)=> itemArray [指数] .value的[元]
                                 )
                             );
    }
    其他
        产生中断; //处理,其中IsQuantized()返回false的情况下...
}

Basically I have a collection of objects each implement a member of Type IValueCollection

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

MeasurementCollection.Values is of type IValueCollection.

With the logic below I want to pivot a collection of IValueCollection and wrote the extension method below.

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

should do {{1,2,3}{4,5,6}{7,8,9}} results in {{1,4,7},{2,5,8},{3,6,9}} However I think there is some nicer, slimmer and more readable expression to do this can somebody point me in the right direction?

edit info about underlying classes

    interface IValueCollection : IEnumerable<decimal>

    class MeasurementCollection : ICollection<IMeasurement>

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

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

解决方案

I would, personally, force the evaluation of your collection in advance, and use it as an array. Right now, each time you call ElementAt, you're going to evaluate the IEnumerable<T> again, causing a lot of repeated searching.

By forcing it to evaluate to an array in advance, you simplify the entire process. Something like:

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

If you control MeasurementValueCollection, I would add a constructor which takes an IEnumerable<decimal> as input, as well. You could then do:

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

这篇关于旋转阵列的集合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆