MATLAB関数の一部の戻り値をエレガントに無視する方法は?


120

それn-1より前のすべての戻り値に対してダミー変数を作成する必要なしに、関数から「n番目」の戻り値を取得することは可能ですか?

たとえば、MATLABに次の関数があるとします。

function [a,b,c,d] = func()
a = 1;
b = 2;
c = 3;
d = 4;

ここで、3番目の戻り値のみに関心があると仮定します。これは、ダミー変数を1つ作成することで実現できます。

[dummy, dummy, variableThatIWillUse, dummy] = func;
clear dummy;

しかし、これはちょっと醜いと思います。次のようなことができると思いますが、できません。

[_, _, variableThatIWillUse, _] = func;

[, , variableThatIWillUse, ] = func;

variableThatIWillUse = func(3);

variableThatIWillUse = func()(3);

これを行うエレガントな方法はありますか?


これまでのところ、最善の解決策は、単にvariableThatIWillUseダミー変数として使用することです。これにより、ワークスペースを汚染する(またはクリアする必要がある)実際のダミー変数を作成する必要がなくなります。要するに、解決策はvariableThatIWillUse、興味深いものまでのすべての戻り値にfor を使用することです。後の戻り値は単に無視できます。

[variableThatIWillUse, variableThatIWillUse, variableThatIWillUse] = func;

私はまだこれは非常に醜いコードだと思いますが、より良い方法がない場合は、その答えを受け入れます。


私の回答で説明したようにセル配列を使用する以外に、変数名を繰り返すことがおそらく他の唯一の解決策です。うまくいけば、変数名は「variableThatIWillUse」ほど長くはありません。=)
gnovice

実際にそうです。「ダミー」は単なる例でした。通常、「variableThatIWillNotUse」を使用します。他の変数は「variableThatIMightUse」、「variableThatIWillUse2」、「variableThatCanBarelyFitOnA80CharacterLine」という名前です。長い名前と殺人の評価の相関関係を調査しています。;)
ジョルディ

26
実際、R2009bは関数の戻りを無視しているため、「〜」文字を使用してよりエレガントに解決されます。例:[〜、b] = sort(rand(10,1))
ymihere 2009年

1
新しい読者の場合:^が正解です。以下のManWithSleeveの回答を参照してください
A.Wan

1
この例では、3番目の出力引数のみが必要な場合は、次を使用します。[variableThatIWillUse、variableThatIWillUse、variableThatIWillUse] = func; ダミー変数をクリアする必要はありません。より新しいMATLABバージョン> = R2009bの場合、[〜、〜、variableThatIWillUse] = func;を使用します。
Thierry Dalon、2016

回答:


38

これは多少ハックですが、うまくいきます:

まず簡単なサンプル関数:

Func3 = @() deal(1,2,3);
[a,b,c]=Func3();
% yields a=1, b=2, c=3

ここで重要なのは、複数式の割り当ての左側で変数を2回使用すると、前の割り当てが後の割り当てによって破棄されることです。

[b,b,c]=Func3();
% yields b=2, c=3

[c,c,c]=Func3();
% yields c=3

(編集:確認するためだけに、この手法が機能することを[mu,mu,mu]=polyfit(x,y,n)確認しました(あなたが気にするすべてがpolyfit3番目の引数である場合)。


編集:より良いアプローチがあります。代わりにManWithSleeveの回答を参照してください。


7
このように解決することを考えていませんでした。しかし、私はこの解決策が賢さの意図の明確さを犠牲にしていると感じています。
ユッカダーボン

5
私は個人的に[junk、junk、c] = function_call()を使用し、 "junk"は重要な変数ではないことと、大量のメモリが含まれている場合は必要に応じてクリアすることの両方を想定しています。
Jason S

5
反対投票:なぜ-1 この回答はR2009bがリリースされる前に書かれていたため、@ ManWithSleeveの回答は当時は機能しませんでした。もちろん、これは正しいアプローチです。
Jason S

2
おそらくあなたの答えの最初の行のコメントは役に立ちますか?私はグーグルを通じてここに来たので、更新する価値があるようです。
FvD 2013

左から右への割り当ては、The MathWorksによって正式に保証されているわけではないため、[c、c、c] = myFunc()の後にcを使用することに頼るべきではありません。(ここのコメント#26を参照:blogs.mathworks.com/loren/2009/09/11/…
Matt Krause

226

MATLABバージョン7.9(R2009b)では、〜を使用できます。たとえば、

[~, ~, variableThatIWillUse] = myFunction();

これ,はオプションではないことに注意してください。入力[~ ~ var]するだけでは機能せず、エラーがスローされます。

詳細については、リリースノートを参照してください。


3
「_」ではないのがちょっと面倒です。(私はそれがすでに取られたと思いますか?)
SamB

4
@SamB:not演算子を使用するのdon't careもそれほど悪くはありませんが
Tobias Kienzler

28
これ,はオプションではないことに注意してください。入力[~ ~ var]するだけでは機能せず、エラーがスローされます。
eykanal 2011

これが「正しい」答えだと思います。もう1つは、存在しない問題を修正するためのハックだけです。しゃれは意図していません...
patrik

6
質問はR2009bより前の2009年に提起されましたが、その時点では〜は機能しませんでした。
トムアンダーソン

37

変数をビットバケットに入れるために残されるスタイルを使用したい場合、妥当な代替策は次のとおりです。

[ans,ans,variableThatIWillUse] = myfun(inputs);

ansはもちろん、MATLABのデフォルトのジャンク変数であり、セッション中に頻繁に上書きされます。

私は、MATLABで現在許可されている新しいトリックを気に入っていますが、〜を使用して無視される戻り変数を指定していますが、これは下位互換性の問題であり、古いリリースのユーザーはコードを使用できません。私は一般的に、少なくともいくつかのMATLABリリースが発行されてユーザーが非常に少ないままになるまで、そのような新しいものの使用を避けます。たとえば、今でも、匿名関数を使用できないほど古いMATLABリリースを使用していることがわかりました。


7
はい、賢いですが、ans変数に何かを割り当てると、ネイティブのMatlabエディターが警告を表示します。警告することはとてもエレガントだとは思いません...
ジョルディ

11
警告をオフにすることができます。このコメント文字列で行を終了します%#ok Mlintはこれを無視します。警告はありません。

13

使用できる別のオプションを次に示します。まず、セル配列を作成してすべての出力をキャプチャします(NARGOUT関数を使用して、特定の関数が返す出力の数を決定できます)。

a = cell(1,3);  % For capturing 3 outputs
% OR...
a = cell(1,nargout(@func));  % For capturing all outputs from "func"

次に、次のように関数を呼び出します。

[a{:}] = func();

そして、単にから要素を削除したいこと、および上書き:

a = a{3};  % Get the third output

9

私はkth out関数を書きました:


function kth = kthout(k,ffnc,varargin)
%% kthout: take the kth varargout from a func call %FOLDUP
% 
% kth = kthout(k,ffnc,varargin)
%
% input:
%  k                      which varargout to get
%  ffnc                   function to call;
%  varargin               passed to ffnc;
% output:
%  kth                    the kth argout;
% global:
% nb: 
% See also:
% todo:
% changelog: 
%
%% %UNFOLD

[outargs{1:k}]  = feval(ffnc,varargin{:});
kth                         = outargs{k};

end %function

次に電話できます

val_i_want  = kthout(3,@myfunc,func_input_1,func_input_2); %etc

次のような関数をラップすることもできます

func_i_want = @(varargin)(kthout(3,@myfunc,varargin{:}));  %assuming you want the 3rd output.

その後あなたは使う

val_i_want = func_i_want(func_input_1,func_input_2);

このような無名関数の使用に関連するオーバーヘッドがあることに注意してください。これは、何千回も呼び出されるコードで行うことではありません。


4

Matlab 2010aで、私はあなたが求めていることをうまく行う方法を見つけました。それは単にダミー変数として(もちろん引用符なしで)文字 "〜"を使用することです(複数のパラメーターを返すときに必要なだけ)。関数が欠落データを処理するように設計されている場合、これは関数への入力パラメーターに対しても機能します。これが以前のバージョンに存在していたかどうかはわかりませんが、最近発見されました。


11
前の答えを見ませんでしたか?

1

選択した出力のみを返す関数(または無名関数)を作成できます。

select = @(a,b) a(b);

次に、次のように関数を呼び出すことができます。

select(func,2);
select(func,1:3);

または、出力を変数に割り当てることができます。

output(1,2:4) = select(func,1:3);

私にはうまくいきません。試したdecimatedfftx = select(fft(x,12),1:4:12);
NotGaeL

1
select(func,2)を呼び出しますfunc(2)。これが出力引数を選択する場所がわかりません。
Cris Luengo

0

次のように、ans(n)を使用しない理由はありますか?

a=rand([5 10 20 40]);

size(a);

b=ans(2);

b = 10が得られ、この方法はすべてのMatlabバージョンと互換性があるわけではないでしょうか?

さらに、これは、引数の数がわからない場合に2番目の出力引数を取得するために機能します。一方、これを行うと:

[~, b] = size(a);

次にb = 8000!(より多くの引数をキャッチするには、〜で終わる必要があります!)


この答えは、返される変数がベクトルであることを前提としています。これは、おそらくOPが意図したものではありませんでした。
Neil Traft 2015年

これは意味がありません。さまざまなものsize(a)[b,c]=size(a)返します。MATLABの関数は、出力引数の数に基づいて動作を変更します。
クリスLuengo

この答えを理解するのに苦労しています。これがここでの回答の質にどのように寄与するのかはわかりませんが、これが元の質問に直接回答しないことは言うまでもありません。
rayryeng

それは6年後、Matlabを使用しなくなりました。私が覚えている限りでは、関数「size()」は無関係でした。複数の引数を返す関数として使用しただけです。ポイントは、単にfunc()を呼び出してから、ans(n)を呼び出して、返された変数nの値を取得できることです。これは特定の状況でうまく機能し、後方互換性があるように見えました。もちろん、それは特定の関数、または変数の型を問わず、機能するだけです。それは6年後に私ができる限りです。
user1596274
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.