In R2016b, MATLAB introduced a new string datatype, in addition to the usual char datatype. So far, so good, but it is now giving me a lot of issues with the JSONlab toolbox I'm using.
For instance, in R2015b, loadjson
returns a 1x3 cell character array:
dd = loadjson('["Titi", "Toto", "Tata"]') dd = 'Titi' 'Toto' 'Tata'
But in R2018a, loadjson
returns a 1x3 string array:
dd = loadjson('["Titi", "Toto", "Tata"]') dd = 1×3 cell array {["Titi"]} {["Toto"]} {["Tata"]}
For not having to change my code everywhere, I'd like to patch the loadjson
routine to replace all string
types it may return with char
types. For instance, in the following cell array:
test = { 'hello', "world", 0.3; 'how', 'are', "you"} test = 2×3 cell array {'hello'} {["world"]} {[0.3000]} {'how' } {'are' } {["you" ]}
I'd like to replace all strings:
cellfun(@isstring, test) ans = 2×3 logical array 0 1 0 0 0 1
Is there a way I can do it quickly (i.e. without looping through all elements) ?
PS: I know of jsondecode and jsonencode to replace JSONLab in the future, but so far I just want to quickly patch things.
To pass data from a string array to such functions, use the cellstr function to convert the string array to a cell array of character vectors. Create a string array. You can create strings using double quotes. Convert the string array to a 1-by-3 cell array of character vectors.
To create a cell array of character vectors, use curly braces, {} , just as you would to create any cell array. For example, use a cell array of character vectors to store a list of names. The character vectors in C can have different lengths because a cell array does not require that its contents have the same size.
newStr = strrep( str , old , new ) replaces all occurrences of old in str with new . If any input argument is a nonscalar string array or cell array of character vectors, then the other input arguments must have compatible sizes.
You can use cellstr
(confusingly, despite "str" suggesting string) to convert strings to character arrays without looping or cellfun
... the docs state the following:
C = cellstr(A)
convertsA
to a cell array of character vectors. The input arrayA
can be a character array, a categorical array, or, starting in R2016b, a string array.
test = {'hello', "world", 0.3; 'how', 'are', "you"}; % multi-type test cell array ind = cellfun(@isstring, test); % indexing for string type items test(ind) = cellstr(test(ind)) % char-ify the strings!
A cellfun
performance note for class checks:
In both mine and Luis' answers, cellfun
is used to determine which elements are strings. You can improve the performance of cellfun
for this task...
Per the cellfun
docs, there are some character array options which are much quicker than their function-handle counterparts. For the isstring
indexing, it's likely a lot faster to run the first of these:
% rapid ind = cellfun('isclass', test, 'string'); % akin to looping ind = cellfun(@isstring, test);
They have the same output, in a simple test I see a 4x speed improvement:
% Create large test array of random strings c = cell(100,1000); c = cellfun(@(x) string(char(randi([65,122],1,10))), c, 'uni', 0); % Create functions for benchmarking f=@()cellfun('isclass', c, 'string'); g=@()cellfun(@isstring,c); % Timing on MATLAB R2017b timeit( f ) % >> 0.017sec timeit( g ) % >> 0.066sec
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With