0

I am working on a project where by I need to find all possible permutations of an array.

I have this working, to a point

var geneticsArray = new[] { new[] { "M", "V" }, new[] { "M", "V" }};
var perms = from a in geneticsArray[0]
            from b in geneticsArray[1]

            select new { a, b };

This presents me with all the options:

  • MM
  • VM
  • MV
  • VV

Which is correct, but it isnt what I want to achieve, as for my intents and purposes VM and MV are one and the same.

How do I get the convert MV to VM?

This example is very simple and only contains 2 groupings, there are infinite groupings possible, which is something I will deal with later, but just want to make you aware so the reply wasnt simply reverse the result.

Any help with this would be great.

Further Edit

With the following code I can see a count of each permutation:

var permCounts = from perm in perms group perm by perm into b select new { b.Key, Count = b.Count() };

This will tell me each of the afore mentioned options occurs once, which is not quite right, as outline above MV and MV are, in this case, the same. I need the code to understand this.

This is what I am looking for, not how to make it able to deal with a unknown number of combinations.

Thanks

3
  • Have a look at this project which covers many permutation- and combination requirements: codeproject.com/Articles/26050/… Commented Apr 17, 2012 at 11:53
  • Your code doesn't make any sense. I wouldn't compile because of e,f,g,h and even if it did compile, it wouldn't work anyway, because you're going beyond the bounds of the array. Commented Apr 17, 2012 at 12:04
  • @svick thanks for pointing that out, I had copy and pasted it from a larger working example, the code is now correct Commented Apr 17, 2012 at 12:09

2 Answers 2

1

How about this?

        var perms = from a in geneticsArray[0]
                    from b in geneticsArray[1]

                    select new string[] { a, b };

        var dict = new Dictionary<string, int>();
        foreach (var ent in perms)
        {
            Array.Sort(ent);
            var _ent = string.Join(",", ent);
            if (dict.ContainsKey(_ent))
            {
                dict[_ent]++;
            }
            else
            {
                dict.Add(_ent, 1);
            }
        }

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

Comments

0

This will do we trick:

var geneticsArray = new[] { new[] { "M", "V" }, new[] { "M", "V" } };
var perms = from a in geneticsArray[0]
            from b in geneticsArray[1]
            where a.CompareTo(b) >= 0
            select new { a, b };

Also it is easier to work with lists of different size with recursion (take a look at this post by Eric Lippert - http://ericlippert.com/2010/06/28/computing-a-cartesian-product-with-linq/)

5 Comments

the example code has been updated and now will compile... copy and paste errors :(
And i thought link to Eric's post will be useful for you, but of course this post did not answer your question
Aye, now I can see that. OP wants unique permutations; Eric's code gives non-unique combinations.
@Nikolay your code will not work because you can't compare strings that way. But where a.CompareTo(b) >= 0 should work
@SteveMallory You are right, i just though it is obvious how to do it with strings too. Fixed my answer.

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.