tags:

views:

254

answers:

6

Hello,

I've noticed something about my coding that is slightly undefined. Say we have a two dimension array, a matrix or a table and we are looking through it to check if a property is true for every row or nested dimension.

Say I have a boolean flag that is to be used to check if a property is true or false. My options are to:

  1. Initialize it to true and check each cell until proven false. This gives it a wrong name until the code is completely executed.
  2. Start on false and check each row until proven true. Only if all rows are true will the data be correct. What is the cleanest way to do this, without a counter?

I've always done 1 without thinking but today it got me wondering. What about 2?

A: 

Make the property name something like isThisTrue. Then it's answered "yes" or "no" but it's always meaningful.

In Ruby and Scheme you can use a question mark in the name: isThisTrue?. In a lot of other languages, there is a convention of puttng "p" for "predicate" on the name -- null-p for a test returning true or false, in LISP.

Charlie Martin
+9  A: 

Depends on which one dumps you out of the loop first, IMHO.

For example, with an OR situation, I'd default to false, and as soon as you get a TRUE, return the result, otherwise return the default as the loop falls through.

For an AND situation, I'd do the opposite.

Will Hartung
A: 

I agree with Will Hartung.

If you are worried about (1) then just choose a better name for your boolean. IsNotSomething instead of IsSomething.

Martin
Is that a clear name though?(For some reason Stackoverflow just added three comment boxes)
Improfane
A: 

Personally I just throw the whole loop into a somewhat reusable method/function called isPropertyAlwaysTrue(property, array[][]) and have it return a false directly if it finds that it finds a case where it's not true.

The inversion of logic, by the way, does not get you out of there any quicker. For instance, if you want the first non-true case, saying areAnyFalse or areAllTrue will have an inverted output, but will have to test the exact same cases.

This is also the case with areAnyTrue and areAllFalse--different words for the exact same algorithm (return as soon as you find a true).

You cannot compare areAnyFalse with areAnyTrue because they are testing for a completely different situation.

Bill K
+2  A: 

They actually both amount to the same thing and since you say "check if a property is true for every row or nested dimension", I believe the first method is easier to read and perhaps slightly faster.

You shouldn't try to read the value of the flag until the code is completely executed anyway, because the check isn't finished. If you're running asynchronous code, you should guard against accessing the value while it is unstable.

Both methods "give a wrong name" until the code is executed. 1 gives false positives and 2 gives false negatives. I'm not sure what you're trying to avoid by saying this - if you can get the "correct" value before fully running your code, you didn't have run your code in the first place.


How to implement each without a counter (if you don't have a foreach syntax in your language, use the appropriate enumerator->next loop syntax):

1:

bool flag = true;

foreach(item in array)
{
    if(!check(item))
    {
        flag = false;
        break;
    }
}

2:

bool flag = false;
foreach(item in array)
{
    if(!check(item))
    {
        break;
    } 
    else if(item.IsLast())
    {
        flag = true;
    }
}
lc
Thank you, I like this answer. How clean you personally find it?
Improfane
+3  A: 

Go with the first option. An algorithm always has preconditions, postconditions and invariants. If your invariant is "bool x is true iff all rows from 0-currentN have a positve property", then everything is fine.

Don't make your algorithm more complex just to make the full program-state valid per row-iteration. Refactor the method, extract it, and make it "atomic" with your languages mechanics (Java: synchronized).

Marcel J.