1

I have a for loop in C# as below,

int[] dim1, dim2, dim3;
//Initialize dim1, dim2 and dim3
for(int i = 0; i < dim1.Length; i++)
{   
    DoSomething1(i);
    for(int j = 0; j < dim2.Length; j++)
    {
        DoSomething2(i, j);
        for(int k = 0; k < dim3.Length; k++)
        {
            DoSomething3(i, j, k);
        }    
    }
}

My problem is that sometimes the dimension of array dim2 would be 0, then DoSomething2() and DoSomething3() will not be executed. Is there any way to bypass the second for loop if dim2.Length = 0? That is, when dim2.Length = 0, I want the whole for loops to behave like below,

int[] dim1, dim2, dim3;
//Initialize dim1, dim2 and dim3
for(int i = 0; i < dim1.Length; i++)
{   
    DoSomething1(i);

    for(int k = 0; k < dim3.Length; k++)
    {
        DoSomething3(i, k);
    }    
}

Moreover, the for loops might be many dimensions (I will have dim1, dim2, dim3, dim4, ..., dimn), and except for the length of dim1, the length of any other array might be 0. Is there any good way to do this? Thanks!

4
  • 2
    It's not clear exactly what you're trying to accomplish here. You're describing two very different semantics. Jun 8, 2016 at 20:26
  • Hi Mason, I reedited my question. If it's still not clear, please post again. Thanks!
    – Ames ISU
    Jun 8, 2016 at 20:30
  • In order for the first code snippet to make sense the arrays have to be somehow related or at least have their members used in the inner loops. Otherwise you're just saying I want to run DoSomething3 n number of times. Where n = dim1.Length * dim2.Length * dim3.Length.
    – Max Sorin
    Jun 8, 2016 at 20:30
  • 1
    To me, the nesting of the loops implies some relationship between the three arrays. If the middle piece of the relationship is missing, what are you trying to accomplish on the last piece? You'll be missing information in the call to DoSomething3()
    – cdkMoose
    Jun 8, 2016 at 20:35

2 Answers 2

3

Since the logic you want to execute is conceptually the same for every "dimension", and the only thing that varies is the array you loop over and the function you call in that loop, I'd simply use a recursive function which takes array and function arguments. I don't know C# all that well, but I assume the core of that approach would look something like this:

public delegate void IntConsumer(List<int> ints);

public static void doStuff(List<List<int>> arrays, List<IntConsumer> consumers) {
    processArrays(arrays, consumers, new List<int>());
}

private static void processArrays(List<List<int>> arrays,
                                  List<IntConsumer> consumers,
                                  List<int> consumerArgsSoFar) {
    if(consumers.Count == 0 || arrays.Count == 0) {
        return;
    }

    List<int> currentArray = arrays[0];
    List<List<int>> remainingArrays = arrays.GetRange(1, arrays.Count-1);
    IntConsumer currentConsumer = consumers[0];
    List<IntConsumer> remainingConsumers = consumers.GetRange(1, arrays.Count-1);

    if(currentArray.Count == 0) {
        processArrays(remainingArrays, remainingConsumers, consumerArgsSoFar);
    } else {
        for(int i = 0; i < currentArray.Count; i++) {
            List<int> consumerArgs = new List<int>(consumerArgsSoFar);
            consumerArgs.Add(currentArray[i]);

            currentConsumer(consumerArgs);

            processArrays(remainingArrays, remainingConsumers, consumerArgs);
        }
    }
}

Complete, working version of this example: https://ideone.com/HXrIXd

Now the number of dimensions is entirely up to the caller of doStuff(), without the caller having to manage any of this "skipping empty dimensions" logic. I assume that's what you were looking to achieve, based on your comment on Mason's answer.

0
0

Is there any way to bypass the second for loop if dim2.Length = 0?

Sure. Use an if statement that reads almost exactly like what you just wrote:

int[] dim1, dim2, dim3;
//Initialize dim1, dim2 and dim3
for(int i = 0; i < dim1.Length; i++)
{   
    DoSomething1();

    if (dim2.Length == 0)
    {
        for(int k = 0; k < dim3.Length; k++)
        {
            DoSomething3();
        }    
    }
    else 
    {
        for(int j = 0; j < dim2.Length; j++)
        {
            DoSomething2();
            for(int k = 0; k < dim3.Length; k++)
            {
                DoSomething3();
            }    
        }
    }
}

Although this seems like such an obvious answer that there's probably something missing. Would this fix your problem, or are there more details to worry about?

2
  • Right, that could only solve this special case. I didn't put the question clear. So my really question is the for loop might be many dimensions (I will have dim1, dim2, dim3, dim4, ..., dimn), and except for the length of dim1, the length of any other array might be 0. If I use the if statement, it would be too complicated. Any better solution to this?
    – Ames ISU
    Jun 8, 2016 at 20:40
  • @AmesISU Incorporate that information into your actual question and I'll retract my close vote (and once I learn how to pass function arguments in C#, probably post an answer too).
    – Ixrec
    Jun 8, 2016 at 20:47

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.