0

I have a sanctions api that i need to call, passing in a string of values. these values are constructed as follows:

string searchString = string.Join(" ", myList.ToArray());
// remove any numbers and return complete words
MatcCollection strMatch = Regex.Matches(searchString, @"[^\W\d]+");

var values = strMatch.Cast<Group>().Select(g => g.Value).ToArray();

var combinations = values.Permutations();

Now, that i have the array i need, i call the Permutations method below:

public static IEnumerable<IEnumerable<T>> Permutations<T>(this IEnumerable<T> source)
    {
        if (source == null)
            throw new ArgumentException("source");
        return permutations(source.ToArray());
    }

the permutations method is:

private static IEnumerable<IEnumerable<T>> permutations<T>(IEnumerable<T> source)
    {
        var c = source.Count();
        if (c == 1)
            yield return source;
        else
            for (int i = 0; i < c; i++)
                foreach (var p in permutations(source.Take(i).Concat(source.Skip(i + 1))))
                    yield return source.Skip(i).Take(1).Concat(p);
    }

With a example list of 7 items {one,two,three,four,five,six,seven} this code returns numerous list of 7 elements in lenght.

What I need to create is the following:

First iteration:

return result = one

Second iteration return result = one + ' ' + two

so on and so

I got the above exmple code from a post on SO, so don't know how to change it properly to get what i need.

2

1 Answer 1

2

So do I get right that not only you want all permutations of the 7 items, but also any subsets of them enumerated (something like all combinations)?

I guess the simplest way to get that behaviour would be adding some sort of length-parameter to the permutations method:

private static IEnumerable<IEnumerable<T>> permutations<T>(IEnumerable<T> source, int length)
{
    var c = source.Count();
    if (length == 1 || c == 1)
        foreach(var x in source)
            yield return new T[] { x };
    else
        for (int i = 0; i < c; i++)
            foreach (var p in permutations(source.Take(i).Concat(source.Skip(i + 1)), length - 1))
                yield return source.Skip(i).Take(1).Concat(p);
}

and then calling this method with parameters from 1 to n:

public static IEnumerable<IEnumerable<T>> Permutations<T>(this IEnumerable<T> source)
{
    if (source == null)
        throw new ArgumentException("source");
    var src = source.ToArray();
    for (int i = 1; i <= src.Length; i++)
        foreach (var result in permutations(src, i))
            yield return result;
}

Hope I didn't make any typos...

Sign up to request clarification or add additional context in comments.

11 Comments

the list olydis, could be any number, 7 was the example i'm running through at the moment.
In my response I also just wanted to address that very example - my code does not expect it to be 7, does it? ;)
couple of errors with this Olydis: Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<T>' to 'System.Collections.Generic.IEnumerable<System.Collections.Generic.IEnumerable<T>>'. An explicit conversion exists (are you missing a cast?) and Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<T>' to 'T'. An explicit conversion exists (are you missing a cast?)
ok that sorted that one, but still complains about yield return new T[] {source}
Nice one. Is it possible to return a string for each item. it's currently an array. for example value = one value = one two value = one two three etc
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.