将一系列元素合并到定义数量的块C#中

时间:2015-01-18 18:37:19

标签: c# linq ienumerable

我需要创建一个方法Package<T>,给定一系列T类型的接口,int nT default,将序列的元素放入n + 1个块,这样我就可以在每个块的第一个元素(即一个接口)上调用一个方法,并使用每个块的其他n个接口的内部元素作为该方法的参数。如果存在没有足够参数的块,则必须使用default来填充块。

让我们用整数做一个例子。假设我有一个接口IMyInterface<int>,它使用sum作为要调用的方法。 s是12个IMyInterfaces的序列,每个IMyInterfaces分别包含前12个整数中的一个,从0开始(所以[0-11])。我的Package方法的其他参数是n = 3和default = 20.

然后我期待的是3个整数的列表:6(即= 0 + 1 + 2 + 3),22(即= 4 + 5 + 6 + 7),38(即= 8) + 9 + 10 + 11)。 (默认不使用)。

如果n == 4,它会改变,我希望列出3个整数:10(0 + 1 + 2 + 3 + 4),35(5 + 6 + 7 + 8 + 9),81(10 + 11) + 20 + 20 + 20)(此处默认用于填充最后一个块的三个剩余整数)。

以下是方法:

IEnumerable <T> Package <T >( IEnumerable < IMyInterface<T>> sequence , int n, T default )

这是界面:

public interface IMyInterface <T>
{
    T MergeWith ( params T[] others );
    T InnerElem { get; }
}

我希望这个解释足以理解我的问题。

1 个答案:

答案 0 :(得分:1)

以下是解决方案的外观:

public interface IMyInterface<T>
{
    T MergeWith(params T[] others);
    T InnerElem { get; }
}

public class C : IMyInterface<int>
{
    public C(int elem)
    {
        InnerElem = elem;
    }

    public int MergeWith(params int[] others)
    {
        return others.Sum() + InnerElem;
    }

    public int InnerElem { get; private set; }
}

class Program
{
    static void Main(string[] args)
    {
        var items = Enumerable.Range(0, 12).Select(x => new C(x));

        foreach (var item in Package(items, 4, 20))
        {
            Console.WriteLine(item);
        }
    }

    static IEnumerable<T> Package<T>(
        IEnumerable<IMyInterface<T>> sequence, 
        int n, T def)
    {
        return sequence
            .Select((x, ix) => new { item = x, ix })
            .GroupBy(x => x.ix / (n+1))
            .Select(x =>
            {
                var first = x.First().item;
                var others = x.Skip(1).Select(z => z.item.InnerElem);
                var missing = n - others.Count();
                var missingItems = Enumerable.Range(0, missing).Select(_ => def);

                return first.MergeWith(others.Concat(missingItems).ToArray());
            });
    }
}