0

For a long time now I've been in the habit of checking whether a collection (array, dictionary, whatever) is non-empty with a nonequality. Like this:

if ( MyArray.Length < 1 )
{
    // Do something if the array is empty
}

Sometimes I do this for strings too, and other kinds of collections. In practice, this should be the same as

if ( MyArray.Length == 0 )
{
    // Do something if the array is empty
}

Because the length of collection should never be less than 0 anyway, right? So I always thought - what the heck, I'll include the inequality and be double-safe even in the case the sky falls down.

But today a though struck me that the second version might be more readable than the first. It expresses more clearly that the case I'm looking for is the empty array, which is not immediately apparent from the first version. So maybe I should use that instead? Since, you know, if a collection length is less than 0, then I'm screwed anyway.

Which version do you use, and which would you suggest others to use (and why)?

Clarification: This was meant as a question about simple collections, where obtaining .Length is O(1) or otherwise inexpensive. If .Length itself is a nontrivial operation (such as necessitating the iteration through a linked list, or contacting the DB), then this is the wrong approach altogether.

The question was about x < 1 vs x == 0 where x is a nonnegative integer (although it might not be typed as such).

1
  • 1
    The second version for exactly the reasons you listed. Commented May 25, 2012 at 11:05

4 Answers 4

8

Some collection that is empty has length of zero.

Some collection with a negative length is something else.

Use second one or implement a method like IsEmpty().

7
  • Oh, I'm not thinking hard. It's just a thought that struck me as I was doing work today, and since I couldn't decide on my own in a few moments, I posted it here. :)
    – Vilx-
    Commented May 25, 2012 at 11:09
  • 7
    +1 for IsEmpty(). This one does make it really clear. Plus it can be faster than getting the size for some containers. Commented May 25, 2012 at 11:15
  • I'm not sure I agree that this is such a trivial thing... IsEmpty() is a generally preferred mechanism because it is simultaneously closer to how we think about the condition we're trying to describe, and easily executed by computer. We come to understand this sort of thing best by factoring out complicated domain logic, so that we're left with trivial problems like the OP described. Further, it can be important to have a consistent style, and it's best to have that style be based upon reason. Commented May 25, 2012 at 11:26
  • Actually you are right, sorry for calling that trivial. Commented May 25, 2012 at 11:27
  • 1
    For some containers an IsEmpty approach is not just faster than .Length == – the latter may actually be impossible! For instance in the case of lazy lists, which can be infinite. Commented May 25, 2012 at 12:15
1

Personally, I think that neither version is good, and both are a sign of bad API design on part of the author of Array.

For example, in Ruby (not that I would propose the Ruby core library as an example of good API design) it would be

do_something if my_array.empty?

Which coincidentally is almost the same as your English prose comment.

It also helps making your code more generic, because checking for emptiness is possible in O(1) steps for almost all collections, whereas computing the length may take as long as O(n) (in case of a linked list, for example) or even forever (in case of an infinite lazy stream).

Think about

list_of_all_primes.empty?

vs.

list_of_all_primes.length.zero? # Oops.
1
  • As I commented to @leftaroundabout - naturally, if getting .length is a lengthy operation, or other special conditions apply, then this is the wrong approach altogether. This question was for simple collections where getting length is a O(1) operation.
    – Vilx-
    Commented May 25, 2012 at 12:58
0

Considering just "==" and "<", the question, it seems to me, is what are you going to do if the length is negative? The most intelligent thing to do is ignore the question, because it's not going to happen. Having failed at that, the proper thing to do is stop the program and set off alarms because something is very wrong indeed. But no one is going to do that either. So lastly, you need to consider the best course of action with a negative value. I'd say most of the time treating it as zero (using "< 1") is the safest route. But I would try to psychoanalyze whoever wrote the collection and base my final decision on that.

Note that "< 1" is the easiest route. If -5 does not mean the collection is empty, does it mean there is an element 4? Or does it mean there is an element -4? If you want to be consistent, if you use "== 0" you need to code to handle negative lengths when the length doesn't equal zero. So, in general, I'll vote for "< 1".

2
  • For "<0"? Seriously? That pollutes your code with lots of branches that will most likely never be taken. Commented May 27, 2012 at 13:16
  • Oops. Should be "< 1". I fixed it. Thanks. Commented May 27, 2012 at 20:56
0

I would first check if there is a method named "empty", "isEmpty" or similar. The reason: Your check MyArray.Length < 1 determines the length of the array, even though you are not interested in the length at all, only in the fact that it is 0 or not 0. For some instances with a huge length, determining the length might be quite time consuming, while detecting that the length is not zero is immediate.

Say you have a string class, with "length" returning the number of Unicode code points. But internally the string is stored in UTF-8 format. If there is a million bytes, then to determine the "length" you need to look at each single byte. On the other hand, checking that the lengthis not zero is trivial.

Or take a linked list. Checking that it has more than 0 elements is trivial, but actually calculating the length can be quite time consuming.

Your Answer

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

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