2010-02-25 14 views
42

Voici un exemple de ce que je cherche:Comment faire des affectations multiples dans MATLAB?

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

J'avais attendre quelque chose comme ça après:

>> x 

x = 

    88 

>> y 

y = 

    12 

Mais au lieu que j'obtiens des erreurs comme:

??? Too many output arguments. 

Je pensais que deal() pourrait le faire, mais il semble ne fonctionne que sur les cellules.

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

Comment résoudre mon problème? Dois-je constamment indexer par 1 et 2 si je veux les traiter séparément?

+3

affaire ne fonctionne que si foo est une cellule. Vous avez défini foo comme un tableau standard. C'est pourquoi tu as le '' ??? Référence de contenu de cellule à partir d'un objet de tableau non-cellule. –

Répondre

40

Vous n » t besoin de deal du tout (modifier: pour Matlab 7.0 ou version ultérieure) et, pour votre exemple, vous n'avez pas besoin de mat2cell; vous pouvez utiliser num2cell sans autre argument ::

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

x = 

    88 


y = 

    12 

Si vous souhaitez utiliser deal pour une autre raison, vous pouvez:

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

x = 

    88 


y = 

    12 
+3

Juste une note de côté, je pense que vous ne pouvez vous en tirer avec ne pas utiliser deal (comme dans le premier exemple) dans Matlab 7+. –

+0

Intéressant. Je ne savais pas que l'accord est inutile de nos jours. Cependant, j'ai utilisé mat2cell à dessein, puisque je suppose que l'OP pourrait vouloir séparer les colonnes les unes des autres. – Jonas

+1

C'est vraiment bon. Mais y a-t-il un moyen de tout avoir sur une seule ligne? Peut-être quelque chose comme: '[x y] = num2cell (foo) {:}' (Désolé, toujours confus par Matlab assez souvent.) –

1

DEAL est vraiment utile, et vraiment déroutant. foo doit être un tableau de cellules lui-même, je crois. Ce qui suit semble fonctionner dans Octave, si je me souviens bien, il travaillera en Matlab ainsi:

> foo = {88, 12} 
foo = 

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

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

Qu'est-ce que mtrw dit. Fondamentalement, vous voulez utiliser traiter un tableau de cellules (bien que deal (88,12) fonctionne aussi bien).

En supposant que vous commencez avec un foo tableau qui est n par 2 et que vous souhaitez attribuer la première colonne à x et la seconde à y, vous procédez comme suit:

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

Notez que deal accepte une « liste » comme argument, non un tableau de cellules. Ainsi, les travaux suivants comme prévu:

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

y = 12 

La syntaxe c{:} transforme une matrice de cellules dans une liste et une liste est un comma separated values, comme dans les arguments de la fonction. Cela signifie que vous pouvez utiliser la syntaxe c{:} comme argument pour d'autres fonctions que deal. Pour voir cela, effectuez les opérations suivantes:

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

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

Pour utiliser la solution num2cell dans une ligne, définissez une fonction d'assistance 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

ne sera pas l'exemple '[[a1, a2, a3, a4] = liste (1: 4)' cause "Trop d'arguments de sortie" erreur? – zhangxaochen

1

Je ne peux pas commenter d'autres réponses, donc plus séparée.

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

deal peut être utilisé comme une doublure pour les non-scalaires ainsi, bien sûr, si vous les avez déjà dans des variables distinctes, dites:

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

et maintenant vous les traitez avec une ligne:

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

Toutefois, s'ils sont compressés dans une variable, vous ne pouvez les ajouter que s'ils sont dans une cellule ou un tableau de structure - avec deal(X{:}) pour le tableau de cellules et deal(S.field) pour le tableau de structure. (Dans ce dernier cas, un seul champ est traité, mais de toutes les structures dans le tableau.) Avec Matlab v.7 +, vous pouvez utiliser X{:} et S.field sans deal, comme indiqué dans les autres réponses.

0

créer une fonction arr2vars pour plus de commodité

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 

Vous pouvez l'utiliser alors comme ce

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

Vous cherchez peut-être

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

entraînant

x = 
    88 

y = 
    12 

Donc, vous avez un one-liner de travail.

1

Il existe un moyen plus simple.

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

Fournit

>> x 

x = 

88 

>> y 

y = 

12 

Documentation complète à Mathworks.

Questions connexes