2010-02-25 6 views
42

Ecco un esempio di quello che sto cercando:Come si eseguono assegnazioni multiple in MATLAB?

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

avevo aspettano qualcosa di simile in seguito:

>> x 

x = 

    88 

>> y 

y = 

    12 

Ma invece ricevo errori come:

??? Too many output arguments. 

Pensavo che lo deal() potesse farlo, ma sembra funzionare solo sulle celle.

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

Come posso risolvere il mio problema? Devo indicizzare costantemente per 1 e 2 se voglio gestirli separatamente?

+3

Deal funziona solo se foo è una cella. Hai definito foo come array standard. Ecco perché hai ottenuto il ??? Riferimento al contenuto della cella da un oggetto dell'array non cellulare. Messaggio di errore. –

risposta

40

È don' t necessario deal (modificare: per Matlab 7.0 o versioni successive) e, per l'esempio, non è necessario mat2cell; è possibile utilizzare num2cell senza altri argomenti ::

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

x = 

    88 


y = 

    12 

Se si desidera utilizzare deal per qualche altro motivo, è possibile:

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

x = 

    88 


y = 

    12 
+3

Solo una nota a margine, penso che si possa fare a meno di non usare deal (come nel primo esempio) in Matlab 7+. –

+0

Interessante. Non sapevo che l'affare non è necessario al giorno d'oggi. Tuttavia, ho usato mat2cell di proposito, poiché presumo che l'OP possa voler separare le colonne l'una dall'altra. – Jonas

+1

Questo è veramente buono. Ma c'è un modo per avere tutto su una riga? Forse qualcosa del tipo: '[x y] = num2cell (foo) {:}' (Scusa, ancora confuso da Matlab abbastanza spesso.) –

1

DEAL è davvero utile e davvero confuso. foo deve essere un array di celle stesso, credo. Quanto segue sembra funzionare in Octave, se non ricordo male che funzionerà in MATLAB così:

> foo = {88, 12} 
foo = 

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

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

Cosa mtrw detto. Fondamentalmente, vuoi usare deal con un array di celle (anche se deal (88,12) funziona pure).

Supponendo che si avvia con una foo array che è n-by-2, e che si desidera assegnare alla prima colonna per x e la seconda a y, effettuare le seguenti operazioni:

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{:}); 
11

Nota che deal accetta una "lista", come argomento non, un array di celle. Quindi, le seguenti opere come previsto:

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

y = 12 

La sintassi c{:} trasforma un array di celle in un elenco, e una lista è un comma separated values, come in argomenti della funzione. Ciò significa che è possibile utilizzare la sintassi c{:} come argomento per altre funzioni rispetto a deal. Per vedere che, provare quanto segue:

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

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

utilizzare la soluzione num2cell in una sola riga, definire una funzione di supporto list:

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

varargout = num2cell(x); 

end 
+0

non nell'esempio '[a1, a2, a3, a4] = lista (1: 4)' causa errore 'Troppi argomenti di output'? – zhangxaochen

1

Non posso commentare le altre risposte, oltre in modo separato.

you can use deal(88,12) if you are starting from scalars

deal può essere utilizzato come un one-liner per i non-scalari pure, naturalmente se già li avete in variabili separate, dire:

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

e ora li avete a che fare con una riga:

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

Tuttavia, se sono imballati in una variabile, è possibile solo deal se si trovano in una cella o array di strutture, con deal(X{:}) per array di celle e deal(S.field) per array di strutture. (Nell'ultimo caso viene distribuito solo un campo, ma da tutte le strutture nell'array.) Con Matlab v.7 + è possibile utilizzare X{:} e S.field senza deal, come indicato in altre risposte.

0

Crea un arr2vars funzione per convenienza

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 

si può utilizzare poi come questo

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

Si potrebbe essere alla ricerca di

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

conseguente

x = 
    88 

y = 
    12 

Quindi hai un solo rivestimento funzionante.

1

C'è un modo più semplice.

x = foo (1, 1) 
y = foo (1, 2) 

Fornisce

>> x 

x = 

88 

>> y 

y = 

12 

La documentazione completa a Mathworks.