0

I need to create a method Package<T> that, given a sequence of interfaces of type T, an int n and a T default, put the elements of the sequence in n+1 blocks, so that i can invoke a method on the first element(that is a interface) of every block and use the inner elements of the other n interfaces of each block as parameters of that method. If there's a block without enough parameters to be used, then the default must be used to full the block.

Let's do an example with integers. Suppose i've got an interface IMyInterface<int> that uses the sum as the method to be invoked. s is the sequence of twelve IMyInterfaces, each one containing respectively one of the first 12 integers, starting from 0 (so [0-11]). The other arguments of my Package method are n=3 and default=20.

Then what i'm expecting is a list of 3 integers: 6 (that is = 0+1+2+3), 22(that is = 4+5+6+7), 38(that is = 8+9+10+11). (default is not used).

If n==4 it changes and i expect a list of 3 integers: 10 (0+1+2+3+4), 35(5+6+7+8+9), 81(10+11+20+20+20) (here default is used to fill the three remainig integers of last block).

Here's the method:

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

and here's the interface:

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

I hope this explanation is enough to understand my question.

Sanci
  • 119
  • 3
  • 13
  • 1
    It would really help if you'd give your example in *code* rather than as a *description*. Showing `IMyInterface` would be helpful too. – Jon Skeet Jan 18 '15 at 18:42
  • 2
    It is not clear how interface `IMyInterface` used? How should group of `IMyInterface` to be converted into `T`? May be one more parameter should be introduced in the `Package` method? – ie. Jan 18 '15 at 18:43
  • My problem is that what i've got is a description of what this method should do and i can't understand how to do that. I understood the example, but i don't know how to traslate it to code. – Sanci Jan 18 '15 at 18:44
  • The one with the integers. Btw i added the interface. That's all i got. – Sanci Jan 18 '15 at 18:46
  • 1
    Half of the question is probably duplicate of "split sequence into groups of predefined sizes" questions like http://stackoverflow.com/questions/17059235/linq-get-data-as-quaternary-packs.... Complete solution likely will include healthy dose of other LINQ methods like `Concat`, `First` and possibly `Aggregate`. Feels a bit too broad to me as each of separate steps have many SO answers already. – Alexei Levenkov Jan 18 '15 at 18:53

1 Answers1

1

Here is how the solution could looks like:

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());
            });
    }
}
ie.
  • 5,982
  • 1
  • 29
  • 44
  • That's exactly what i was looking for! Thanks ie., you made my day! That Linq implementation of the method was my aim! – Sanci Jan 18 '15 at 19:31