R2016bでは、MATLABは通常の char データ型に加えて、新しい string データ型を導入しました。これまでのところ、とても良いですが、今使っている JSONlab ツールボックスに多くの問題が生じています。
たとえば、R2015bでは、loadjson
は1x3セルcharacter配列を返します。
dd = loadjson('["Titi", "Toto", "Tata"]')
dd =
'Titi' 'Toto' 'Tata'
しかし、R2018aでは、loadjson
は1x3string配列を返します。
dd = loadjson('["Titi", "Toto", "Tata"]')
dd =
1×3 cell array
{["Titi"]} {["Toto"]} {["Tata"]}
どこでもコードを変更する必要がないため、loadjson
ルーチンにパッチを適用して、返されるすべてのstring
型をchar
型で置き換えるようにします。たとえば、次のセル配列では、
test = { 'hello', "world", 0.3; 'how', 'are', "you"}
test =
2×3 cell array
{'hello'} {["world"]} {[0.3000]}
{'how' } {'are' } {["you" ]}
すべての文字列を置き換えたい:
cellfun(@isstring, test)
ans =
2×3 logical array
0 1 0
0 0 1
(つまり、すべての要素をループすることなく)すばやく実行できる方法はありますか?
PS:私は jsondecode と jsonencode を将来的にJSONLabに置き換えることを知っていますが、これまでのところ、パッチをすばやく適用したいと思っています。
cellstr
(混乱しますが、 "str"がstringを示唆しているにもかかわらず)ループを行わずに文字列を文字配列に変換したり、cellfun
...ドキュメントは次のように述べています:
C = cellstr(A)
はA
を文字ベクトルのセル配列に変換します。入力配列A
は、文字配列、カテゴリカル配列、またはR2016b以降では文字列配列にすることができます。
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
クラスチェックのパフォーマンスノート:
私の回答とLuisの回答の両方で、cellfun
を使用して、どの要素が文字列であるかを判断します。このタスクのcellfun
のパフォーマンスを改善できます...
cellfun
docsによると、対応する関数ハンドルよりもはるかに高速な文字配列オプションがいくつかあります。 isstring
インデックスの場合、最初のインデックスを実行する方がはるかに高速です:
% rapid
ind = cellfun('isclass', test, 'string');
% akin to looping
ind = cellfun(@isstring, test);
それらは同じ出力を持ち、簡単なテストでは4倍の速度向上が見られます。
% 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
MATLAB R2017b以降は convertstringstochars を使用できます:
[test{:}] = convertStringsToChars(test{:});
cellfun
を使用できますが、パフォーマンスはループとほぼ同じです。
test = {'hello', "world", 0.3; 'how', 'are', "you"};
ind = cellfun(@isstring, test);
test(ind) = cellfun(@char, test(ind), 'UniformOutput', false)
別の解決策 ndocumentedMATLABブログで説明 は、controllib.internal.util.hString2Char
の「半文書化された」関数です。これはあなたがそれを使う方法です:
test = { 'hello', "world", 0.3; 'how', 'are', "you"};
fixed_test = controllib.internal.util.hString2Char(test);
fixed_test =
2×3 cell array
{'hello'} {'world'} {[0.3000]}
{'how' } {'are' } {'you' }
ブログの投稿によると、この関数は入力を再帰的に実行するため、次のような状況でも機能します。
test = {"target1", struct('field',{123,'456',"789"})};
ft = controllib.internal.util.hString2Char(test);
{ft{2}.field}
ans =
1×3 cell array
{[123]} {'456'} {'789'}
いくつかの警告については、ブログ投稿をご覧ください。