2010-02-25 64 views
42

Dưới đây là một ví dụ về những gì tôi đang tìm kiếm:Làm cách nào để thực hiện nhiều phép gán trong MATLAB?

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

tôi muốn mong đợi một cái gì đó như thế này sau đó:

>> x 

x = 

    88 

>> y 

y = 

    12 

Nhưng thay vào đó tôi nhận được lỗi như:

??? Too many output arguments. 

Tôi nghĩ deal() có thể làm điều đó, nhưng dường như chỉ hoạt động trên các ô.

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

Làm cách nào để giải quyết sự cố của tôi? Tôi có phải liên tục lập chỉ mục 1 và 2 nếu tôi muốn giải quyết riêng cho họ không?

+3

Deal chỉ hoạt động nếu foo là một tế bào. Bạn đã xác định foo là một mảng chuẩn. Đó là lý do tại sao bạn có '??? Tham chiếu nội dung ô từ thông báo lỗi mảng object.'. –

Trả lời

40

Bạn don' t cần deal ở tất cả (chỉnh sửa: cho Matlab 7.0 trở lên) và, ví dụ của bạn, bạn không cần mat2cell; bạn có thể sử dụng num2cell không có đối số khác ::

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

x = 

    88 


y = 

    12 

Nếu bạn muốn sử dụng deal đối với một số lý do nào khác, bạn có thể:

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

x = 

    88 


y = 

    12 
+3

Chỉ cần một lưu ý phụ, tôi nghĩ rằng bạn chỉ có thể nhận được ngay với không sử dụng thỏa thuận (như trong ví dụ đầu tiên) trong Matlab 7+. –

+0

Thú vị. Tôi không biết rằng thỏa thuận đó là không cần thiết hiện nay. Tuy nhiên, tôi đã sử dụng mat2cell với mục đích, vì tôi cho rằng OP có thể muốn tách các cột khỏi nhau. – Jonas

+1

Điều này thực sự tốt. Nhưng có cách nào để có tất cả trên một dòng? Có lẽ một cái gì đó như: '[x y] = num2cell (foo) {:}' (Xin lỗi, vẫn còn nhầm lẫn bởi Matlab khá thường xuyên.) –

1

DEAL thực sự hữu ích và rất khó hiểu. foo cần phải là một mảng tế bào chính nó, tôi tin. Sau đây dường như hoạt động trong Octave, nếu tôi nhớ chính xác nó cũng sẽ hoạt động trong MATLAB:

> foo = {88, 12} 
foo = 

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

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

mtrw nói gì. Về cơ bản, bạn muốn sử dụng đối phó với một mảng ô (mặc dù thỏa thuận (88,12) hoạt động là tốt).

Giả sử bạn bắt đầu với một foo mảng đó là n-by-2, và bạn muốn gán cột đầu tiên để x và thứ hai để y, bạn thực hiện như sau:

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

Lưu ý rằng deal chấp nhận một "danh sách" như là đối số, không phải một mảng ô. Vì vậy, các công trình sau đây như mong đợi:

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

y = 12 

Cú pháp c{:} biến đổi một mảng tế bào trong một danh sách, và một danh sách là một comma separated values, giống như trong đối số chức năng. Có nghĩa là bạn có thể sử dụng cú pháp c{:} làm đối số cho các hàm khác ngoài deal. Để thấy rằng, hãy thử như sau:

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

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

Để sử dụng giải pháp num2cell trong một dòng, định nghĩa một hàm helper 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

sẽ không là ví dụ '[a1, a2, a3, a4] = danh sách (1: 4)' gây ra 'Quá nhiều đối số đầu ra 'lỗi? – zhangxaochen

1

Tôi không thể bình luận câu trả lời khác, bổ sung rất riêng biệt.

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

deal có thể được sử dụng như một lớp lót cho người không vô hướng là tốt, tất nhiên nếu bạn đã có chúng trong các biến riêng biệt, nói:

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

và bây giờ bạn xử lý chúng với một dòng:

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

Tuy nhiên, nếu chúng được đóng gói trong một biến, bạn chỉ có thể deal chúng nếu chúng nằm trong mảng ô hoặc cấu trúc - với deal(X{:}) cho mảng ô và deal(S.field) cho mảng cấu trúc. (Trong trường hợp sau chỉ có một trường được xử lý, nhưng từ tất cả các cấu trúc trong mảng.) Với Matlab v.7 +, bạn có thể sử dụng X{:}S.field mà không cần deal, như được ghi trong các câu trả lời khác.

0

Tạo một hàm arr2vars để thuận tiện

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 

Bạn có thể sử dụng nó sau đó như thế này

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

Bạn có thể tìm kiếm

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

dẫn đến

x = 
    88 

y = 
    12 

Vì vậy, bạn có một lớp lót hoạt động.

1

Có cách dễ dàng hơn.

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

Cung cấp

>> x 

x = 

88 

>> y 

y = 

12 

Full tài liệu tại Mathworks.

Các vấn đề liên quan