Why is an empty string not empty? isempty('') returns true, but isempty("") returns false
80 ビュー (過去 30 日間)
古いコメントを表示
(Updated to clarify the problem)
Strings, added in R2016b, are a great addition to matlab, but one aspect is a problem: testing for empty variables with isempty() no longer gives a consistent response.
>> isempty('')
ans =
logical
1
>> isempty("")
ans =
logical
0
% even though comparison for equality is 'true':
>> '' == ""
ans =
logical
1
One would expect that if the two values are considered equal, that a builtin function like isempty() would produce the same result.
Presumably "" is not empty because it is a string object, while '' really is the same as [ ]. But this is a problem for code that tests for empty character input using isempty(...). It no longer works as expected if passed "" instead of ''. Is there a switch we can turn on or off to enable isempty("") to return true?
A function written prior to R2016b never needed to check for empty "" (double-quoted) strings, because Matlab would throw an exception if passed something in double quotes. Now, that code produces incorrect results if a user passes in an empty double-quoted string.
One can, of course, test using strlength(...)==0, but IIRC, the Matlab IDE gave a warning about efficiency for this, and recommended using isempty(...).
4 件のコメント
Stephen23
2018 年 1 月 19 日
編集済み: Stephen23
2018 年 1 月 19 日
" The problem is that code written prior to R2016b never had to test for input of "" "
The solution is not to create a totally misleading and inconsistent definition of empty. You need to bite the bullet and update your code. And probably improve the input checking to make sure that it only works with data types that work properly.
回答 (6 件)
Kelly Kearney
2018 年 1 月 19 日
I think string arrays function more like cell arrays in this context... the first element of the string itself isn't empty, but the contents of that element are:
>> y = "";
>> whos y
Name Size Bytes Class Attributes
y 1x1 132 string
>> isempty(y)
ans =
logical
0
>> isempty(y{1})
ans =
logical
1
4 件のコメント
Stephen23
2018 年 1 月 19 日
編集済み: Stephen23
2018 年 1 月 19 日
"The problem is that existing code which checks for empty strings using isempty(...) no longer works correctly if a user passes it an empty string (in double quotes) instead of a char array (in single quotes)"
That isn't a "problem" at all, because that is actually the correct behavior: a scalar string is a scalar string, no matter how many characters it might contain.
"no longer works correctly"
MATLAB works correctly. What you are proposing is totally inconsistent, as the size of a string array is totally unrelated to how many characters might be contained in any one element of that array. That is in fact the whole point of string arrays.
Star Strider
2018 年 1 月 19 日
Another option is the strlength (link) function. It appears to give the correct results for both string and character arrays:
chr1 = '';
chr2 = 'ab';
str1 = "";
str2 = "ab";
lenstr1 = strlength(str1)
lenstr2 = strlength(str2)
lenchr1 = strlength(chr1)
lenchr2 = strlength(chr2)
lenstr1 =
0
lenstr2 =
2
lenchr1 =
0
lenchr2 =
2
so there is no need to test the variable type, only the length.
3 件のコメント
Star Strider
2018 年 1 月 19 日
You could use isnumeric to test for numeric variables (including the empty array [] that returns true), and if that returns false, then test with strlength.
Experiment with this anonymous function with various arguments:
mtstr = @(x) ~isnumeric(x) && (strlength(x) == 0);
The ‘&&’ short-circuits the function so strlength will not ‘see’ numeric inputs.
Stephen23
2018 年 1 月 19 日
" I'm trying to find a clean solution that avoids going back through thousands of lines of code written prior to R2016b and rewriting all my tests for empty strings."
You need to accept that different MATLAB versions have different features and can behave in different ways. You can either pick one version and stick with it, or accept that newer versions made some changes and ensure that your code matches that. The decision is yours. (This applies to all languages of course, not just MATLAB)
Your proposal of creating a totally inconsistent definition of empty is certainly not a "clean solution".
Ian
2018 年 1 月 19 日
5 件のコメント
Stephen23
2018 年 1 月 20 日
編集済み: Stephen23
2018 年 1 月 20 日
What has been deprecated?
"the use of isempty(...) to test for empty strings"
No, isempty correctly tests for empty strings, exactly as it should. It certainly has not been deprecated. A 2x1 string is NOT empty, a 1x1 string is NOT empty (no matter how many characters it contains), and a 1x0 string is empty. Try it:
isempty(strings(1,0)) % a 1x0 string really is empty!
What you are claiming is that
strings(1,1) % scalar string with no characters
should be classified as empty. Under your inconsistent definition of empty (where 1x1 string with zero characters is empty) this 1x4 string array would cause four iterations of this loop:
S = ["ABC","DEF","GHI","JK"] % 1x4 string array
while ~isempty(S), S=S(2:end), end
whereas this 1x4 string array would iterate three times:
S = ["ABC","DEF","GHI",""] % 1x4 string array
while ~isempty(S), S=S(2:end), end
and apparently this would not iterate even once!:
S = ["","","",""] % 1x4 string array.
while ~isempty(S), S=S(2:end), end
Even though all of them are 1x4 string arrays, you have just invented a definition of empty that magically changes how many times my loop iterates, not depending on the size of the array itself (which is what MATLAB currently does) but depending on the number of characters within the string array. If you then decide that a 1x4 string array should obviously cause it to iterate four times, then how many times should it for a 1x3 string? Or a 1x2 string? Or a 1x1 string? Or a 1x0 string?
Oh... Actually I think I like this more and more: I could use this to avoid doing lots of work: "sorry I could not process your data: you entered the test name as an empty string and as a result my code just skipped that iteration entirely, and so I never knew about it". You have me convinced!
Nothing has been deprecated. isempty is totally correct.
PS: actually I could not figure out how many iterations this string array ["","","",""] would result in using your inconsistent definition of isempty:
- four times? (disagrees with you insisting that 1x1 can be empty)
- three times? (because only the last iteration would be a 1x1 string with zero characters, fitting your definition).
- zero times? (because all four of the string elements have zero characters).
Three times seems to fit your definition, but would mean that that loop runs a different number of times depending on what data is contained in the string, and not on the size of the string itself! So in some cases your definition causes my 1x4 string to be iterated over four times, sometimes maybe three times... and I cannot use size or numel to tell me!
Oh, if only MATLAB had implemented some consistent definition of isempty, so that my loop always iterated over all of my 1x4 arrays (not matter what class) consistently four times! Oh wait... that is exactly what MATLAB already does!
PPS: What about ["","","","ABC"]? Your special isempty definition has me totally flummoxed on this one. Please advise how it would work!
Ian
2018 年 1 月 19 日
編集済み: Ian
2018 年 1 月 19 日
10 件のコメント
Walter Roberson
2018 年 1 月 20 日
Mathworks uses
matlab.io.internal.utility.convertStringsToChars
to do the conversion on argument lists. That is, you can use
[varargin{:}] = matlab.io.internal.utility.convertStringsToChars(varargin{:});
Brian Kim
2021 年 4 月 28 日
You can also do
xChar = convertStringsToChars(x);
tf = isempty(xChar);
Jim Riggs
2018 年 1 月 19 日
As near as I can tell, Matlab does not use the double quote character, so
isempty("")
is not a valid statement.
5 件のコメント
Walter Roberson
2018 年 1 月 20 日
The use of double quotes on input was introduced in R2017a, but string objects were introduced in R2016b.
Ian
2018 年 1 月 19 日
6 件のコメント
Stephen23
2018 年 1 月 20 日
編集済み: Stephen23
2018 年 1 月 20 日
"Note, BTW, that matlab considers "" and '' to be equal:"
"Therefore I would not say that it is unreasonable to expect a builtin function like isempty(...) to produce identical results for the two inputs."
eq for strings is very much an overloaded convenience operator, as the help describes: "If one input is a string array, the other input can be a string array, a character vector, or a cell array of character vectors. The corresponding elements of A and B are compared lexicographically".
Lexicographical equivalence does not imply that any of these different arrays are in any other ways identical.
参考
カテゴリ
Help Center および File Exchange で Argument Definitions についてさらに検索
製品
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!