質問: matlab r2019aでsubstrが見つかりません。原因はなんでしょうか? matlab r2019a でsubstrが見つかりません。原因はなんでしょうか? ドキュメンテーションを確認したところ、r2018bから導入されているらしいのですが、コマンドを叩いても表示されず困っています。
回答: 僕の場合は自分で作りました。 substr = (@(s_or_c, i, n)feval(@(c, i, n) c(i:(i+n-1)),feval(@(s_or_c) char(s_or_c),s_or_c),i,n)); これをコマンドラインにコピペすれば、substrを書き換えたりclear substrしたりしない限り、substrが利用可能になります。 substr("hello world", 2, 6) と打てば「'ello w'」が返ります。 以下、解説 入力cが文字ベクトル(1重引用符で括られたもの)のとき、 「無名関数」というのを利用して定義すればいいです。 substr = @(c,i,n) c(i:(i+n-1)); とすることで、substrが実現します。 無名関数 @(x, ..) 関数や演算子など(x, ..); は、 function rtn = anonymous(x, ..) rtn = 関数や演算子など(x, ..) end のようなanonymous.mが「あるとみなして」anonymous(x, ...)を返してくれという命令です。 つまり、先ほどのコードでは、 function rtn = anonymous(c, i, n) rtn = c(i:(i+n-1)); end がある とみなして、 substr = anonymous(c,i,n); をやったのと同じです。 例えば substr('hello world', 2, 6) は'ello w'を返却します。 しかし、ここにはまだ問題が残っています。 substr("hello world", 2, 6) は機能しないのです。 2重引用符で括られたものは「文字列」であり、文字ベクトルとは別物だからです。 文字列は、char(文字列)のようにすることで文字ベクトルに変換できます。 (蛇足: ちなみにchar(文字ベクトル)は、そっくりそのまま文字ベクトルを返します) したがって、 substr(char("hello world"), 2, 6) ならokです。 ただ、これではダサいですよね。 substr("hello world", 2, 6) でもちゃんと動くようにしましょう。 substr = @(str,i,n) char(str)(i:(i+n-1)); ならいいでしょうか? いいえ。 matlabでは、括弧が隣り合うと、エラーになります。 したがって、 substr = @(str,i,n) (c = char(str); c(i:(i+n-1))); でいけそうです。 しかしこれもダメです。無名関数は文を1つしか持たせられないからです。 何とかして無名関数で書きたい場合、 「feval関数」というのを何度も用いることで書けます。 fevalは、次のような関数です。 「feval(@f, x) が f(x) を返却する」 「feval(@g, x, y)が g(x, y)を返却する」 ・・・ 例1: feval(@cos, 3.14) は、cos(3.14)つまり-1を返却します。 例2: feval(@mod, 10,3) は、mod(10,3)つまり1 を返却します。 また、 feval関数の第1引数には無名関数も持ってこれます。 例3: feval(@(c,i,n) c(i:(i+n-1)), 'hello_world', 2, 6) は、substr('hello world', 2, 6)つまり'ello w'を返します。 ややこしいですが、 「'無名関数'内でfevalを利用し、 そのfeval内で'無名関数'を利用し、 その'無名関数'内でfevalを利用し そのfeval内で'無名関数'を利用し、 その'無名関数'内でfevalを利用し そのfeval内で...」 のようなことを繰り返すと、複数の文を無名関数で実行できます。 (理由は、「複数の文」全体を、一つの文としてみることが可能になるからです) いきなり例を示すと混乱するので(もし皆さんが混乱しないとしても、説明している僕のほうが混乱します笑)、 どんな無名関数をつかうか、先に決めましょう。 関数その1: (s_or_c) → c 引数: s_or_c: 文字列かもしれないし文字ベクトルかもしれないもの。 戻り値: c: 確実に文字ベクトル 内容(分かりやすい表現): c = char(s_or_c); 内容(無名関数の書き方で) @(s_or_c) char(s_or_c); 関数その2: (c, i, n) → answer 引数: c i n 戻り値: answer: 得たい部分文字列 内容(分かりやすい表現): answer = c(i:(i+n-1)); 内容(無名関数の書き方で) @(c, i, n) c(i:(i+n-1)); では、これを書いてみましょう。 substr = ... (... @(s_or_c, i, n) ... feval ... %◆ ... %関数その2を無名で定義し、利用します。 %◆ (... %◆ @(c, i, n) c(i:(i+n-1)), ... %◆ ... %関数その2を定義 %◆ ... %◆ feval ... %★ %◆ ... %関数その1を無名で定義し、利用します。%★ %◆ (... %★ %◆ @(s_or_c) char(s_or_c), ... %★ %◆ ... %関数その1を定義 %★ %◆ ... %★ %◆ s_or_c ... %★ %◆ ... %関数その1を利用 %★ %◆ ), ... %★ %◆ ... %★全体がcとして評価される(=あたかもcであるかのように振る舞う) %◆ i, n ... %(★=c)と繋げて読むと、c,i,nとなっている。 %◆ ... %関数その2を利用 %◆ )... %◆ ... %◆全体がanswerとして評価される ); こんな感じです。 それでは、失礼いたします。