Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# for loop - How do I run the loop body with different variables?

Tags:

c#

loops

for-loop

I have several double type variables who for example are named like this: Hight1, Hight2, Hight3, Hight4, ... The values are in no order and can be all over the place but the variables are all numbered chronologically.

Now I want to access the value of those variables and run some code until some condition is met. For example:

bool Result = false;

if (0,3 + Hight1 >= 2)
{
    Result = true;
}
else
{
    if (0,3 + Hight2 >= 2)
    {
        Result = true;
    }
    else
    ...

Now I am pretty new to coding and completely self taught and I just found out about for loops and wanted to make a loop for this since this can go on for dozen of variables and can take up hundreds of lines of code which is quite ugly... So I want to make something like this:

bool result = false
for (int i = 1; result!; i++)
{
    if (0,3 + ("Hight" + i) >= 2)
    {
       result = true;
    }
}

So in the first round the loop should use Hight1, in the second round Hight2 and so on until some condition is met or we have run through alle the variables.

I just can't find out how to code this. I have looked into reflectors and arrays but have only found examples for how to give those chronologically numbered variables some value+i but not how to access them in a chronological order.

Thank you very much.

like image 436
APrioriScience Avatar asked Jun 04 '20 10:06

APrioriScience


2 Answers

Make Height an array.

Something like this:

var result = false;
decimal[] height = { 0.1, 0.2 }; // use your values here
for (var ii = 0; ii < height.Length; ii++) {
  if (0.3 + height[ii] > 2) {
    result = true;
    break;
  }
}
like image 137
Marko Juvančič Avatar answered Nov 10 '22 00:11

Marko Juvančič


Arrays and lists

Whenever you deal with variables with a numbered suffix, nine times out of ten you should be using an array or a list. So instead of:

float height1 = 0.1;
float height2 = 1.8;

You do:

float[] heights = new float[] { 0.1, 1.8 };

//OR

List<float> heights = new List<float>() { 0.1, 1.8 };

Which allows you to use loops to process all elements of the array/list:

for(int i = 0; i < heights.Length; i++) // use heights.Count for a List<float>
{
    // do something with heights[i]
}

Note that for processing each element of a collection, you can instead use a foreach, which means you don't have to manually juggle the index value:

foreach(var height in heights)
{
    // do something with height
}

You can also use LINQ here, which I will get to.


Evaluation logic

I'm not sure why you're doing this:

0.3 + height >= 2

instead of the more sensical:

height >= 1.7

There are cases where it makes sense to write out a calculation (e.g. when expressing a timespan in milliseconds), but this doesn't seem to be one of those cases.
This is just an educated guess though, I can't know for a fact if it makes sense in your case to explicitly express 2 and 0.3 as numbers by themselves (it depends on your domain). However, the answer will continue under the assumption that 1.7 is equally meaningful. If it isn't, then you can substitute your original evaluation back into the code samples provided.

Whenever you deal with logic of this shape:

if( a == b )
{
    myBoolean = true;
}
else
{
    myBoolean = false;
}

This can always be reduced to:

myBoolean = (a == b);

Your logic is slightly different because you have a fallback evaluation, but the same principle applies here, giving you:

result = (height1 >= 1.7) || (height2 >= 1.7);

result will be true only if either of the heights is 1.7 or more.

That being said, if you start using an array, this logic isn't necessary anymore, but I wanted to point it out anyway as it dramatically improves readability and it's a basic skill you should improve to become a better developer.


LINQ

I'm going to skip the full introduction (you can find tutorials online), but what LINQ does for you is essentially give you premade loop functions that perform a particular operation on every element of a collection (list/array).

That's actually what you want here: you want to check every height in the array/list, and you want to know if any of these heights pass a specific check (i.e. >= 1.7).

I highlighted any because the appropriate LINQ method here is called Any(). It takes in a lambda method which describes the evaluation that needs to be performed, and it returns a boolean that is true if at least one element in the collection passes this evaluation.

Your entire code block can be condensed into:

float[] heights = new float[] { 0.1, 1.8 };  // you could use the list as well here

var result = heights.Any(height => height >= 1.7);

Now I want to refer back to the optimized logic that we established in the previous section. What LINQ's Any method does is essentially the same, except that it repeats the evaluations for each element in the collection.

If your collection contains two elements, Any basically does the same as:

var result = (heights[0] >= 1.7) || (heights[1] >= 1.7);

If your collection contains 5 elements, it does the same as:

var result = (heights[0] >= 1.7) || (heights[1] >= 1.7) || (heights[2] >= 1.7) || (heights[3] >= 1.7) || (heights[4] >= 1.7);

This is where the power of LINQ (and loops in general) shows itself: your code will work regardless of how many elements there are in the collection, so you don't need to manually handle every individual element yourself.
This will save you a boatload of effort.

I won't delve into the specifics of LINQ and lambda methods, but I highly advise you look this up in a knowledge repository of your choice as it is a powerful tool that will dramatically simplify any collection juggling you otherwise would have to write out manually.

like image 31
Flater Avatar answered Nov 09 '22 23:11

Flater