0

I have this class which contains int array

 public class Combination { public int[] CombinationSet { get; set; } } 

There is static List with many instances of this class

public static List<Combination> Combinations = new List<Combination>(); 

Now I need methods to find combinations on that list so far I have

For 2

 public static List<Combination> FindCombinations(int x,int y) { if (x == y) { return Combinations.Where( lenght => lenght.CombinationSet.Length == 2) .Where( data => (data.CombinationSet[0] == x && data.CombinationSet[1] == y) || (data.CombinationSet[1] == x && data.CombinationSet[0] == y) ).ToList(); } else { return Combinations.Where( lenght => lenght.CombinationSet.Length == 2) .Where(data => data.CombinationSet.Contains(x) && data.CombinationSet.Contains(y) ).ToList(); } } 

Example : if list contains sets : { 1 , 2} , { 1, 3} , { 1 , 2}

and you would call FindCombination(1,2), you would get back list with two instances

It is working fine however for 4 parameters it would be over 24 rows in else statement. I need maximum of 4 I just wonder if there is some more clever way of doing this.

for 3 it looks like this

 public static List<Combination> FindCombinations(int x, int y,int z) { if(x == y || x == z || y == z) { return Combinations.Where( lenght => lenght.CombinationSet.Length == 3). Where( inner => ( ( inner.CombinationSet[0] == x && inner.CombinationSet[1] == y && inner.CombinationSet[2] == z) || (inner.CombinationSet[0] == x && inner.CombinationSet[2] == y && inner.CombinationSet[1] == z) || (inner.CombinationSet[1] == x && inner.CombinationSet[0] == y && inner.CombinationSet[2] == z) || (inner.CombinationSet[1] == x && inner.CombinationSet[2] == y && inner.CombinationSet[0] == z) || (inner.CombinationSet[2] == x && inner.CombinationSet[0] == y && inner.CombinationSet[1] == z) || (inner.CombinationSet[2] == x && inner.CombinationSet[1] == y && inner.CombinationSet[0] == z) )).ToList(); } else { return Combinations.Where( length => length.CombinationSet.Length == 3 ).Where(data => data.CombinationSet.Contains(x) && data.CombinationSet.Contains(y) && data.CombinationSet.Contains(z) ).ToList(); } } 
9
  • So, I take that you would like a FindCombinations method that takes in an array of combination, not just x, y or z if its for 3 Commented Oct 15, 2018 at 18:20
  • I have a question for your requirements, can you ask for a combination with more numbers than those in CombinationSet? I mean, can you search for {1, 2, 3} when the arrays only contain {1, 2} or {1, 3} for example? Or this doesn't matter? Commented Oct 15, 2018 at 18:21
  • you can ask for doubles triples and quadros. There are different overloads for each case. As for the list itself it can contain array of any length. Commented Oct 15, 2018 at 18:25
  • So, you cannot actually have a generic input for the method? Or can you? Commented Oct 15, 2018 at 18:25
  • Just to make sure I understand the question, you want this method to return a list of all the Combinations where the CombinationSet contains all the ints you pass into the method? What if the CombinationSet contains extra ints as well, will you return these as well? Commented Oct 15, 2018 at 18:27

2 Answers 2

2

If you have an object that contains the the list, you may want to put the logic directly on the object. Although really there is no reason (you've provided) to use an array, so might as well make it a List.

public class Combination { public List<int> CombinationSet { get; set; } public bool IsSequenceEqual(params int[] values) { return CombinationSet.SequenceEqual(values); } public override string ToString() { return string.Join(", ", CombinationSet); } } 

So each Combination doesn't care how many parameters you pass, it just wants to make sure the order and number of items are equal. So extend this to the function:

public static List<Combination> FindCombinations(params int[] values) { var result = _Combinations .Where(c => c.IsSequenceEqual(values)) .ToList(); return result; } 

And seems to work in a DotNetFiddle example:

public static void Main() { _Combinations.Add(new Combination{ CombinationSet = new List<int>{ 1, 2, 3}}); _Combinations.Add(new Combination{ CombinationSet = new List<int>{ 2, 3, 4}}); _Combinations.Add(new Combination{ CombinationSet = new List<int>{ 3, 2, 1}}); _Combinations.Add(new Combination{ CombinationSet = new List<int>{ 1, 2, 3}}); Console.WriteLine("Test 1 (1,2,3)"); foreach(var result in FindCombinations(1,2,3)) { Console.WriteLine(result.ToString()); } Console.WriteLine("Test 1 (3,2,1)"); foreach(var result in FindCombinations(3,2,1)) { Console.WriteLine(result.ToString()); } Console.WriteLine("Test 1 (1,2)"); foreach(var result in FindCombinations(1,2)) { Console.WriteLine(result.ToString()); } } 

resulting in:

Test 1 (1,2,3)

1, 2, 3

1, 2, 3

Test 1 (3,2,1)

3, 2, 1

Test 1 (1,2)

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

2 Comments

Good idea however Test1 should return 123 123 321. As I said I care about instances of Combination not CombinationSequence itself.
Would you like me to update it to handle that? Pretty easy
1

If the order doesn't matter, then just check if all three values are present in the array (don't worry about using an index to check the position of each integer):

return Combinations.Where(c => c.CombinationSet.Contains(x) && c.CombinationSet.Contains(y) && c.CombinationSet.Contains(z)); 

If it must have exactly the number of elements that were passed in, you could add additional AND statements to match the array length, etc.

EDIT: Based on your comment, what if you ordered the integers before comparing, and then returned the Combination only if the ordered sets are identical. This should work as long as the combination must contain the same number of elements that are passed in:

return Combinations.Where(c => c.CombinationSet.OrderBy(i => i).SequenceEqual(new int[] { x, y, z }.OrderBy(j => j))); 

8 Comments

No this doesnt work, that I had before this. It leads to returning (1,2) set when you call FindCombination(2,2)
Are you sure about that? Must have been a typo because this should only return combinationSets that contains x, y and z.
@ZoharPeled - 2 and 2 both exist in the set (1,2) - that's what Universus is getting at... I have revised my answer.
tryed this for duos : return Combinations. Where(length => length.CombinationSet.Length == 2). Where(c => c.CombinationSet.OrderBy(i => i) == new int[] { x, y }. OrderBy(j => j)). ToList(); doesnt work
@Universus - see my edit. I changed the == to .SequenceEqual(...) and tested this. x = 1 and y = 2 matches [1, 2] and [2, 1] but not [3, 4] or [2, 2] or [1, 2, 3].
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.