MATLAB: Problem with if-elseif when conditions contain several strings

if elseif strings

Hi community,
I noticed a problem with the following code:
year = '2001'
if year == '2000'
a = 1
elseif year == '2006' | year == '2007' | year == '2008' | year == '2009' | year == '2010' | year == '2011' | year == '2014' | year == '2015'
a = 2
end
Somehow this code gives out a = 2, which obviously is not wanted, as the conditions of the elseif line are not met.
If I just set one of the years as the elseif-condition without "|", the code does not give out a = 2, which is fine.
I know that I can use double numbers instead of strings, which works correctly.
So I don't need a solution, but an explanation, why this occurs…
Can you reproduce this false outcome?
Has matlab a general problem with strings in if conditions?
Or do I have an understanding problem how if-elseif works?

Best Answer

"So I don't need a solution, but an explanation, why this occurs..."
The first thing to do when trying to understand what your code is doing is to actually look at what your code is doing. Lets have a look at your logical comparison:
>> year = '2001';
>> year == '2000'
ans =
1 1 1 0
With character arrays == eq provides an element-wise comparison, so your 4x1 input character arrays return a 4x1 logical array, as the above example shows. Note how the last character of those two vectors are not the same, and hence the corresponding false in the output vector.
Now lets read the if documentation and see what it says about the conditional expression: " An expression is true when its result is nonempty and contains only nonzero elements (logical or real numeric). Otherwise, the expression is false." Consider your 4x1 logical vector: are all of its elements non-zero? (hint no, look at the last one). So your first if condition is NOT true.
You can do the same investigation with your
year == '2006' | year == '2007' | year == '2008' | year == '2009' | year == '2010' | year == '2011' | year == '2014' | year == '2015'
syntax yourself by looking at the resulting logical vector, just ,like I did. And then thinking about how that logical or operator works, and why at the end you will likely just end up with a basically meaningless 4x1 logical vector (which with your example data will contain all true values (and hence does satisfy the if condition)).
"...as the conditions of the elseif line are not met."
Wrong. Now that we have actually read the documentation and looked at your data, we now know that actually the if condition was met: you provided it with a 4x1 logical vector containing only true values.
Eventually you will reach the conclusion that this approach is rather unsuitable for what you are trying to achieve. The correct method is to use strcmp or strcmpi, e.g.:
if strcmp(year,'2006')
or for multiple character vectors use ismember or any wrapped around strcmp:
if ismember(year,{'2006','2007','2008'})
if any(strcmp(year,{'2006','2007','2008'}))
For completeness: if you are using strings (i.e. "") then you can use == to test for equivalence of each string array element, but I would recommend sticking with strcmp as this will give the same expected output for both scalar strings and character vectors, thus making your code more robust.
Related Question