Como faço várias atribuições no MATLAB?

Aqui está um exemplo do que estou procurando:

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

Eu esperaria algo assim depois:

 >> x x = 88 >> y y = 12 

Mas, em vez disso, recebo erros como:

 ??? Too many output arguments. 

Eu pensei que deal() poderia fazer isso, mas parece funcionar apenas em células.

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

Como resolvo meu problema? Devo indexar constantemente por 1 e 2 se eu quiser lidar com eles separadamente?

Você não precisa deal nada (editar: para o Matlab 7.0 ou posterior) e, para o seu exemplo, você não precisa do mat2cell ; você pode usar num2cell sem outros argumentos:

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

Se você quiser usar o deal por algum outro motivo, você pode:

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

Observe que o deal aceita uma “lista” como argumento, não como uma matriz de células. Então, o seguinte funciona como esperado:

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

A syntax c{:} transforma uma matriz de células em uma lista e uma lista é um valor separado por vírgula , como nos argumentos da function. O que significa que você pode usar a syntax c{:} como argumento para outras funções que deal . Para ver isso, tente o seguinte:

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

Para usar a solução num2cell em uma linha, defina uma list funções auxiliares:

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

O que mtrw disse. Basicamente, você quer usar lidar com um array de células (embora deal (88,12) funcione também).

Supondo que você comece com uma matriz foo que é n-por-2 e deseja atribuir a primeira coluna a xea segunda a y, faça o seguinte:

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

O DEAL é realmente útil e muito confuso. foo precisa ser um array de células, creio eu. O seguinte parece funcionar no Octave, se bem me lembro, ele funcionará no MATLAB também:

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

Não posso comentar outras respostas, portanto, adição separada.

você pode usar deal (88,12) se você está começando a partir de escalares

deal pode ser usado como um one-liner para não-escalares, claro, se você já os tiver em variables ​​separadas, diga:

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

e agora você lida com uma linha:

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

No entanto, se eles forem compactados em uma variável, você só poderá deal los se eles estiverem em uma matriz de célula ou estrutura – com deal(X{:}) para matriz de célula e deal(S.field) para matriz de estrutura. (No último caso, apenas um campo é tratado, mas de todas as estruturas no array.) Com o Matlab v.7 + você pode usar X{:} e S.field sem deal , como observado em outras respostas.

Crie uma function arr2vars por conveniência

 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 

Você pode usá-lo assim

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

Você pode estar procurando

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

resultando em

 x = 88 y = 12 

Então você tem uma linha de trabalho.

Existe uma maneira mais fácil.

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

Fornece

 >> x x = 88 >> y y = 12 

Documentação completa no Mathworks.