Вот пример того, что я ищу:
>> foo = [88, 12];
>> [x, y] = foo;
Я бы ожидал чего-то подобного:
>> x
x =
88
>> y
y =
12
Но вместо этого я получаю такие ошибки, как:
??? Too many output arguments.
Я думал, что deal()
может это сделать, но, похоже, работает только с ячейками.
>> [x, y] = deal(foo{:});
??? Cell contents reference from a non-cell array object.
Как я могу решить свою проблему? Должен ли я постоянно индексировать 1 и 2, если я хочу иметь дело с ними отдельно?
Вам вообще не нужно deal
(отредактируйте: для Matlab 7.0 или новее), и для вашего примера вам не нужно mat2cell
; вы можете использовать num2cell
без каких-либо других аргументов::
foo = [88, 12];
fooCell = num2cell(foo);
[x y]=fooCell{:}
x =
88
y =
12
Если вы хотите использовать deal
по какой-либо другой причине, вы можете:
foo = [88, 12];
fooCell = num2cell(foo);
[x y]=deal(fooCell{:})
x =
88
y =
12
Обратите внимание, что deal
принимает "список" в качестве аргумента, а не массив ячеек. Итак, следующее работает так, как ожидалось:
> [x,y] = deal(88,12)
x = 88
y = 12
Синтаксис c{:}
преобразует массив ячеек в список, а список представляет собой значения, разделенные запятыми, как в аргументах функции. Это означает, что вы можете использовать синтаксис c{:}
как аргумент для других функций, чем deal
. Чтобы убедиться в этом, попробуйте следующее:
> z = plus(1,2)
z = 3
> c = {1,2};
> z = plus(c{:});
z = 3
Чтобы использовать решение num2cell
в одной строке, определите вспомогательную функцию list
:
function varargout = list(x)
% return matrix elements as separate output arguments
% example: [a1,a2,a3,a4] = list(1:4)
varargout = num2cell(x);
end
[a1,a2,a3,a4] = list(1:4)
вызвать Too many output arguments
?
Что mtrw. В принципе, вы хотите использовать сделку с массивом ячеек (хотя сделка (88,12) также работает).
Предполагая, что вы начинаете с массива foo, который является n-by-2, и вы хотите назначить первый столбец x, а второй - y, вы делаете следующее:
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{:});
Существует более простой способ.
x = foo (1, 1)
y = foo (1, 2)
Обеспечивает
>> x
x =
88
>> y
y =
12
Полная документация на Mathworks.
Возможно, вы ищете
>>> foo = [88, 12];
>>> [x, y] = deal(foo(1), foo(2))
в результате чего
x =
88
y =
12
Итак, у вас есть рабочий однострочный.
Я не могу комментировать другие ответы, поэтому отдельное дополнение.
вы можете использовать сделку (88,12), если вы начинаете с скаляров
deal
также может использоваться как однострочный для нескалляров, конечно, если вы уже имеете их в отдельных переменных, скажите:
a = 123;
b = rand(3);
c = {a, b};
d = struct('field','val')
и теперь вы обрабатываете их одной строкой:
>> [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'
Однако, если они упакованы в одну переменную, вы можете только deal
их, если они находятся в массиве ячеек или структуры - с deal(X{:})
для массива ячеек и deal(S.field)
для массива структуры. (В последнем случае обрабатывается только одно поле, но из всех структур в массиве.) С Matlab v.7 + вы можете использовать X{:}
и S.field
без deal
, как указано в других ответах.
DEAL действительно полезен и действительно запутан. Я думаю, что foo
должен быть массивом ячеек. Кажется, что в Octave работает, если я правильно помню, что он будет работать и в MATLAB:
> foo = {88, 12}
foo =
{
[1,1] = 88
[1,2] = 12
}
> [x,y] = deal(foo{:})
x = 88
y = 12
Создайте функцию 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
Вы можете использовать его тогда, как это
[~,roi] = imcrop(im);
[x,w,y,h] = arr2vars(roi);
??? Cell contents reference from a non-cell array object.
сообщение об ошибке.