web-dev-qa-db-ja.com

MATLABで複数の割り当てを行うにはどうすればよいですか?

ここに私が探しているものの例があります:

_>> foo = [88, 12];
>> [x, y] = foo;
_

後でexpectのようにします:

_>> x

x =

    88

>> y

y =

    12
_

しかし、代わりに次のようなエラーが表示されます:

_??? Too many output arguments.
_

deal()はそれを行うかもしれないと思ったが、それはセルでのみ機能するようだ。

_>> [x, y] = deal(foo{:});
??? Cell contents reference from a non-cell array object.
_

問題を解決するにはどうすればよいですか?個別に処理したい場合、常に1と2でインデックスを作成する必要がありますか?

43
Benjamin Oakes

dealはまったく必要ありません(編集:Matlab 7.0以降の場合)。例では、mat2cellは不要です。 num2cellを他の引数なしで使用できます::

foo = [88, 12];
fooCell = num2cell(foo);
[x y]=fooCell{:}

x =

    88


y =

    12

他の理由でdealを使用したい場合、次のことができます。

foo = [88, 12];
fooCell = num2cell(foo);
[x y]=deal(fooCell{:})

x =

    88


y =

    12
42
Ramashalanka

deal は、セル配列ではなく「リスト」を引数として受け入れることに注意してください。したがって、以下は期待どおりに機能します。

> [x,y] = deal(88,12)
x = 88

y = 12

構文c{:}は、リスト内のセル配列を変換します。リストは、関数の引数のように カンマ区切り値 です。 c{:}構文をdeal以外の関数への引数として使用できることを意味します。それを確認するには、次を試してください。

> z = plus(1,2)
z = 3

> c = {1,2};
> z = plus(c{:});
z = 3
16
jullybobble

num2cellソリューションを1行で使用するには、ヘルパー関数listを定義します。

function varargout = list(x)
% return matrix elements as separate output arguments
% example: [a1,a2,a3,a4] = list(1:4)

varargout = num2cell(x);

end
8
Sander Evers

mtrw が言ったこと。基本的に、セル配列を扱う必要があります(deal(88,12)も機能します)。

N行2列の配列fooで開始し、最初の列をxに、2番目の列をyに割り当てると仮定すると、次のようになります。

foo = [88,12;89,13;90,14];
%# divide the columns of foo into separate cells, i.e. do mat2cell(foo,3,[1,1])
fooCell = mat2cell(foo,size(foo,1),ones(size(foo,2),1));
[x,y] = deal(fooCell{:});
4
Jonas

他の答えはコメントできないので、別途追加します。

スカラーから開始する場合はdeal(88,12)を使用できます

dealは、非スカラーのワンライナーとしても使用できます。もちろん、既に別の変数に含まれている場合は、次のようにします。

_a = 123;
b = Rand(3);
c = {a, b};
d = struct('field','val')
_

そして今、あなたはそれらを1行で扱います:

_>> [x,y,z,w] = deal(a,b,c,d)
x =
   123
y =
    0.6370    0.2165    0.6711
    0.2945    0.8803    0.2705
    0.7633    0.1537    0.0767
z = 
    [123]    [3x3 double]
w = 
    field: 'val'
_

ただし、それらが1つの変数にパックされている場合、セル配列または構造体配列にある場合はdealのみです。セル配列にはdeal(X{:})、構造体配列にはdeal(S.field)を使用できます。 (後者の場合、1つのフィールドのみが処理されますが、配列内のすべての構造からです。)Matlab v.7 +では、他の回答に記載されているように、dealなしで_X{:}_および_S.field_を使用できます。

1
Victor K

便宜上、関数arr2varsを作成します

function varargout = arr2vars(arr)
% Distribute elements over variables

N = numel(arr);
if nargout ~= N
    error('Number of outputs does not match number of elements')
end
for k = 1:N
    varargout{k} = arr(k);
end

このように使用できます

[~,roi] = imcrop(im);
[x,w,y,h] = arr2vars(roi);
1
Tigliottu

[〜#〜] deal [〜#〜] は非常に便利で、非常に紛らわしい。 fooはセル配列そのものである必要があると思います。以下はOctaveで動作するようです。正しく覚えていれば、MATLABでも動作します:

> foo = {88, 12}
foo =

{
  [1,1] =  88
  [1,2] =  12
}

> [x,y] = deal(foo{:})
x =  88
y =  12
1
mtrw

あなたが探しているかもしれません

>>> foo = [88, 12];
>>> [x, y] = deal(foo(1), foo(2))

その結果

x = 
    88

y = 
    12

だからあなたは働くワンライナーを持っています。

0
luckydonald