Generate a comma-separated list from a numeric array?

Is there a way to generate a comma-separated list from a numeric array without generating a temporary cell array? If not, would you find this functionality useful if it was added to MATLAB?
I know I would - the times that I've wanted to use this construct are very similar to the times that you use {:} with a cell array. For instance, you may have a set of n values in an array A that you want to pass to a function that takes varargin arguments. Right now if you had a cell array C you could do func( C{:} ), but you can't do func( A(someSyntax) ) . Similarly sometimes you want to be able to generate a CSL as an output argument list. Also, sometimes you might want to do B = {1, 2, C{:}, 'foo'}, which is different than B = {1, 2, A(:), 'foo'}. Lastly, you can't do things like a = 3; b=2; c=1; lol = [1 2 3]; [a b c] = deal( lol(someSyntax) )

6 Comments

Matt J
Matt J on 20 Mar 2013
Edited: Matt J on 20 Mar 2013
Apart from your last example (see my Answer below for that), I wouldn't really see much use in creating a CSL from a numeric array. When passing variables as input to functions, it seems more compact to keep them bundled as vectors/matrices if they can exist that way. That also facilitates vectorization. CSL expansion is mainly meant for passing data of different types and sizes that can't co-exist in anything but a cell array.
Your real problem seems to be the habit of defining functions with varargin input syntax when 1 vector input argument would be enough.
Hi Matt, I understand what you're saying - however I was referring to varargin functions that other people have defined, over which you have no control - for example functions that ship with MATLAB, or in codebases you use, etc.
I see what you mean, but then I question whether you should be maintaining your data in matrix form, rather than cell form. If you plan to apply CSL to that data, it may mean that it should have been a cell array to begin with.
I came across this post trying to do something different. The context in which I want to convert a vector to a CSL is for something of the form
[arr.field] = V{:}
where V is the cell array that I create from a vector (from vectorised operations, so it can't be stored as a cell array), and arr is a structure array I want to assign to.
Matt J's solution in terms of vout works, but it still has the inefficiency of creating a cell array for something that Matlab should presumably be able to do efficiently.
If there is a better way to assign to all the elements of a structure array (especially a way to allow something like [arr.field]=0), please let me/us know. Thanks.
[arr.field]=deal(0)
requires no special code. However, striving for efficiency with structure and cell arrays is bound to be unfruitful. Structs and cells are inherently inefficient for storing large data, as compared to vectors and matrices, and you shouldn't really be using them in such situations. Memory access will be slow for one thing because they do not store data contiguously in RAM. If on the other hand, you don't have large data, efficiency isn't really beneficial.
Thanks, Matt J. I hadn't noticed deal() could be used with a scalar.
I agree that matrices are far and away the most efficient where they can be used, but I was assuming that (memory inefficiency) < (memory inefficiency + interpreter inefficiency).

Sign in to comment.

 Accepted Answer

[a b c] = deal( lol(someSyntax) )
This one you can do, and with even easier syntax
>> [a b c] = vout(lol)
a =
1
b =
2
c =
3
where vout() is defined below. You can't do it without creating a temporary cell array, but since this is hidden inside vout(), I don't see why it would matter.
function varargout=vout(C)
if isnumeric(C), C=num2cell(C); end
C=C(:).';
varargout=C(1:nargout);

7 Comments

Yeah, you can do it by defining your own function, but then you have to make sure that everyone that uses you code has access to that function. It is much easier if it's built into MATLAB.
Yes, you would. Although, if your code is small enough to ship as 1 file, I tend to think it's not a big deal to include vout() as a subfunction in that file. Conversely, if you plan to ship a package of files, including 1 more file wouldn't make that much difference.
Could someone be so kind as to post the complete self-contained code for this example, for those of us who may need to experiment with the code to see what is going on and how it works? Thanks.
@FM,
The complete code is posted in my answer.
I plunked your code for vout() into a function num2csl(). I'm a bit confused by the C(:).' -- specifically why the dot. In an array, it makes any operation act on an element-by-element basis rather than on an array basis. Here, I can't see what the role is:
>> c={ 1:3 5:7 (9:12)'}
c =
[1x3 double] [1x3 double] [4x1 double]
>> c(:)
ans =
[1x3 double]
[1x3 double]
[4x1 double]
>> c(:).'
ans =
[1x3 double] [1x3 double] [4x1 double]
>> c(:)'
ans =
[1x3 double] [1x3 double] [4x1 double]
Thanks if you can clarify.
Matt J
Matt J on 28 Jan 2017
Edited: Matt J on 29 Jan 2017
The operator .' is MATLAB's transpose operator,
It just acts here to transpose a column cell array into a row cell array.
Thanks.
I find myself searching for this function again in 2022. It sure would be nice if it can be made native to Matlab. Having an extra function means one more thing that can go wrong if you don't properly sync your library of utility functions between computers, and another dependency to carry when deploying. Additionally, when posting minimal working examples online, it's more code that needs to be carried.

Sign in to comment.

More Answers (0)

Categories

Products

Asked:

on 20 Mar 2013

Commented:

FM
on 23 Oct 2022

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!