Split a list into multiple variables in matlab

If I have a short list (say, two or three elements), I would like to have a function that breaks it into several variables. Something like that:

li=[42 43]; [ab]=split(li) --> a=42 --> b=43 

I am looking for a way to make the code shorter in matlab. This would be good in some situations. For example:

 positions=zeros(10,3); positions= [....]; [xyz]=split(max(positions,1)) 

instead of doing:

 pos=max(positions,1) x=pos(1); y=pos(2); z=pos(3); 
+4
source share
3 answers

The only way I know is to use deal . However, this only works with cell arrays or explicit arguments in deal . Therefore, if you want to deal with matrices / vectors, you first need to convert to an array of cells using num2cell / mat2cell . For instance:.

 % multiple inputs [ab] = deal(42,43) % a=2, b=3 [xyz] = deal( zeros(10,1), zeros(10,1), zeros(10,1) ) % vector input li = [42 43]; lic = num2cell(li); [ab]=deal(lic{:}) % unforunately can't do num2cell(li){:} % a=42, b=43 % matrix input positions = zeros(10,3); % create cell array, one column each positionsc = mat2cell(positions,10,[1 1 1]); [xyz] = deal(positionsc{:}) 

The first form is good ( deal(x,y,...) ), since it does not require the explicit creation of an array of cells.

Otherwise, I think that you should not use deal when you need to convert matrices to cell arrays only for their repeated transformation: just save the overhead. In any case, it still takes 3 lines: first to determine the matrix (for example, li ), then to convert to a cell ( lic ), then do deal ( deal(lic{:}) ).

If you really wanted to reduce the number of lines, there is a solution in this question , where you just make your own function for this, repeat here and modify such that you can define an axis for separation:

 function varargout = split(x,axis) % return matrix elements as separate output arguments % optionally can specify an axis to split along (1-based). % example: [a1,a2,a3,a4] = split(1:4) % example: [x,y,z] = split(zeros(10,3),2) if nargin < 2 axis = 2; % split along cols by default end dims=num2cell(size(x)); dims{axis}=ones([1 dims{axis}]); varargout = mat2cell(x,dims{:}); end 

Then use like this:

 [ab] = split([41 42]) [xyz]= split(zeros(10,3), 2) % each is a 10x1 vector [de] = split(zeros(2,5), 1) % each is a 1x5 vector 

However, the matrix -> cell -> matrix still works. If your vectors are small and you don't do it a million times in a loop, you should be fine, though.

+4
source

You can extract values ​​from a list into different variables with

 li = [42 43 44]; tmp = num2cell(li); [abc] = deal(tmp{:}) a = 42 b = 43 c = 44 
+4
source

You can manage this in one expression if you want:

 a = [1, 2, 3, 4] [b, c, d, e]=feval(@(x)x{:}, num2cell(a)) 

Result:

 b = 1 c = 2 d = 3 e = 4 

If you want to use this a lot, you can quickly make an anonymous function:

 expand = @(A) feval(@(x)x{:}, num2cell(A)) [b, c, d, e]=expand(a) 

I believe that this will work to ensure that num2cell accepts that it doesn't even have to be numeric, it just has to be an array, which is almost everything in Matlab.

+2
source

Source: https://habr.com/ru/post/1387482/


All Articles