it-swarm.com.de

Wie mache ich Mehrfachzuweisungen in MATLAB?

Hier ist ein Beispiel für was ich suche:

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

Ich würde erwarten so etwas danach:

>> x

x =

    88

>> y

y =

    12

Stattdessen bekomme ich Fehler wie:

??? Too many output arguments.

Ich dachte deal() könnte es tun, aber es scheint nur auf Zellen zu funktionieren.

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

Wie löse ich mein Problem? Muss ich ständig mit 1 und 2 indexieren, wenn ich sie separat behandeln möchte?

43
Benjamin Oakes

Sie benötigen deal nicht (Bearbeiten: für Matlab 7.0 oder höher) und für Ihr Beispiel benötigen Sie mat2cell nicht. Sie können num2cell ohne weitere Argumente verwenden:

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

x =

    88


y =

    12

Wenn Sie deal aus einem anderen Grund verwenden möchten, können Sie:

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

x =

    88


y =

    12
42
Ramashalanka

Beachten Sie, dass deal eine "Liste" als Argument akzeptiert, kein Zellenarray. Also das Folgende funktioniert wie erwartet:

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

y = 12

Die Syntax c{:} transformiert ein Zellenarray in eine Liste, und eine Liste besteht aus durch Kommas getrennten Werten , wie in Funktionsargumenten. Das bedeutet, dass Sie die c{:}-Syntax als Argument für andere Funktionen als deal verwenden können. Versuchen Sie Folgendes, um das zu sehen:

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

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

Um die Lösung num2cell in einer Zeile zu verwenden, definieren Sie eine Hilfsfunktion 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

Was mtrw sagte. Grundsätzlich möchten Sie deal mit einem Zellenarray verwenden (obwohl deal (88,12) auch funktioniert).

Angenommen, Sie beginnen mit einem Array foo, das n-by-2 ist, und Sie möchten die erste Spalte x und die zweite Spalte y zuweisen.

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

Andere Antworten kann ich nicht kommentieren, also gesonderte Ergänzung.

Sie können deal (88,12) verwenden, wenn Sie von Skalaren ausgehen

deal kann auch als Einzeiler für Nicht-Skalare verwendet werden, wenn Sie sie bereits in separaten Variablen haben, sagen Sie:

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

und jetzt behandeln Sie sie mit einer Zeile:

>> [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'

Wenn sie jedoch in eine Variable gepackt sind, können Sie sie nur deal verwenden, wenn sie sich in einer Zelle oder einem Strukturarray befinden - mit deal(X{:}) für Zellenarray und deal(S.field) für Strukturarray. (Im letzteren Fall wird nur ein Feld behandelt, aber von allen Strukturen im Array.) Mit Matlab v.7 + können Sie X{:} und S.field ohne deal verwenden, wie in anderen Antworten angegeben.

1
Victor K

Erstellen Sie zur Vereinfachung eine Funktion 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

Sie können es dann so verwenden

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

DEAL ist wirklich nützlich und sehr verwirrend. Ich glaube, foo muss selbst ein Zellenarray sein. Folgendes scheint in Octave zu funktionieren, wenn ich mich recht erinnere, funktioniert es auch in MATLAB:

> foo = {88, 12}
foo =

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

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

Sie könnten suchen

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

ergebend

x = 
    88

y = 
    12

Sie haben also einen funktionierenden Einliner.

0
luckydonald