Finding equivalent to % for the inner if clauses I have a static list of descriptions in a resource and I am filtering down the list based on the index positions of the text in the array

Here is my multi converter:

using OCLMEditor.Data.StudentInfo.Enums;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Windows.Data;

namespace OCLMEditor.ValueConverters
{
    public class StudentAssignmentTypeFilterConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            StudentAssignmentType[] allTypes = values[0] as StudentAssignmentType[];
            List&lt;StudentAssignmentType&gt; filteredTypes = new List&lt;StudentAssignmentType&gt;();
            int iNumberOfClasses = values[1] != null ? (int)values[1] : 0;

            if (iNumberOfClasses == 3) // Main hall, Class 1 and Class 2
                return allTypes;

            if(iNumberOfClasses == 0)
            {
                // What to return? It should not get here as the combo is disabled if 
                return allTypes;
            }

            for(int i = 0; i &lt; allTypes.Length; i++)
            {
                if(iNumberOfClasses &gt;= 1)
                {
                    if (i == 0 || i == 3 || i == 6 || i == 9 || i == 12 || i == 15 || i == 18)
                        filteredTypes.Add(allTypes[i]);
                }

                if(iNumberOfClasses &gt;= 2)
                {
                    if (i == 1 || i == 4 || i == 7 || i == 10 || i == 13 || i == 16 || i == 19)
                        filteredTypes.Add(allTypes[i]);
                }

                if (iNumberOfClasses == 3)
                {
                    if (i == 2 || i == 5 || i == 8 || i == 11 || i == 14 || i == 17 || i == 20)
                        filteredTypes.Add(allTypes[i]);
                }
            }

            return filteredTypes;
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotSupportedException();
        }
    }
}


Do you think the if clauses inside can be simplified somehow?

Specifcally these three if clauses. Eg:

if(iNumberOfClasses &gt;= 1)
{
    if (i == 0 || i == 3 || i == 6 || i == 9 || i == 12 || i == 15 || i == 18)
        filteredTypes.Add(allTypes[i]);
}


I know about using % to get the (modulus(?)) remainder of a division. So if my numbers were 1, 5, 10, 15, 20 I could use number % 5 == 0 to get all of them. But ican't see that I can do that here?
The answer of t3chb0t provides a solution in the right direction. My point of "critique" with that solution is the overdose on LinQ for a simple solution like checking if a collection of numbers contains a certain number.

The point of predefining the collection is a good idea. I would do it like this:

var classesForOne = new [] { 0, 3, 6, 9, 12, 15, 18 };
var classesForTwo = new [] { 1, 4, 7, 10, 13, 16, 19 };
var classesForThree = new [] { 2, 5, 8, 11, 14, 17, 20 };


Now you can check if the variable i is present in a collection. This can be done like this:

if(iNumberOfClasses &gt;= 1)
{
    if (classesForOne.Contains(i))
        filteredTypes.Add(allTypes[i]);
}


Writing it this way, you can combine the two if statements in one simpler statement:

if(iNumberOfClasses &gt;= 1 &amp;&amp; classesForOne.Contains(i))
{
    filteredTypes.Add(allTypes[i]);
}


So the whole code with loop would now look like following:

var classesForOne = new [] { 0, 3, 6, 9, 12, 15, 18 };
var classesForTwo = new [] { 1, 4, 7, 10, 13, 16, 19 };
var classesForThree = new [] { 2, 5, 8, 11, 14, 17, 20 };

for(int i = 0; i &lt; allTypes.Length; i++)
{
    if(iNumberOfClasses &gt;= 1 &amp;&amp; classesForOne.Contains(i))
        filteredTypes.Add(allTypes[i]);

    if(iNumberOfClasses &gt;= 2 &amp;&amp; classesForTwo.Contains(i))
        filteredTypes.Add(allTypes[i]);

    if(iNumberOfClasses == 3 &amp;&amp; classesForThree.Contains(i))
        filteredTypes.Add(allTypes[i]);
}


Edit:

The mod implementation:

This edit is not mandatory, it is just provided as extra information to your secondary question about using the modulus. You CAN implement the modulus-way to achieve the same result. I'm not saying this is a better implementation, just showing how it can be done :) . Let's look at each of the three cases.


{ 0, 3, 6, 9, 12, 15, 18 }


If i is divisible by 3, meaning it has a remainder of 0, it is in the first collection of numbers.


{ 1, 4, 7, 10, 13, 16, 19 }


If i is divided by 3, remainder 1, it is in the second collection.


{ 2, 5, 8, 11, 14, 17, 20 }


And for the last, if i is divided by 3, remainder 2, it is in the third.

Of course using this method you're not validating if the number i is valid within the range. If for example i is 22 (remainder is 1), the result would say that it is present in the second collection. You'll have to build in an extra check for this. Here's the implementation:

for(int i = 0; i &lt; allTypes.Length; i++)
{
    if(iNumberOfClasses &gt;= 1 &amp;&amp; (i &lt;= 18 &amp;&amp; i % 3 == 0))
        filteredTypes.Add(allTypes[i]);

    if(iNumberOfClasses &gt;= 2 &amp;&amp; (i &lt;= 19 &amp;&amp; i % 3 == 1))
        filteredTypes.Add(allTypes[i]);

    if(iNumberOfClasses == 3 &amp;&amp; (i &lt;= 20 &amp;&amp; i % 3 == 2))
        filteredTypes.Add(allTypes[i]);
}


In this way, you don't need to predefine a collection, the counterpart is that you have to built an extra check to set the maximum allowed number. Hope this explains it. :)