Skip to Main Content Skip to Search
File Exchange
MATLAB Newsgroup
Link Exchange
  Blogs  
 Contest 
MathWorks.com

Loren on the Art of MATLAB

January 24th, 2008

Deal or No Deal

This post continues in the theme from my last post, where people routinely come to me on a topic. Today I want to distinguish between indexed assignment, where you can take advantage of scalar expansion, and assignment to several output arrays, often arising from a comma-separated list from cell or struct arrays.

Contents

First Explore Cell Arrays

Let's first explore some aspects of creating and populating the contents of a cell array. I first initialize 2 arrays, each of length 3.

a = {1 magic(3) 'hello'};
d = {'hi' 17 pi};

Next I initialize another cell array to be the same as a.

c = a;

Now I attempt to change the contents of all the cells in c by assigning a new value that I want to show up in each cell.

try
    [c{:}] = 'aloha'; % error unless c is a scalar
catch cellE
    disp(cellE.message)
end
Too many output arguments.

As you can see, this didn't work. The reason is that I have 3 entities on the left-hand side, because c is a cell array of length 3 and I used the comma-separated list notion. MATLAB doesn't know how to make 3 separate arrays out of 1 by simple assignment.

I could use regular indexing on c to populate it however. In this case, the right-hand side has length 1 (a cell array with string contents) and the left-hand side is all of c. MATLAB can do scalar expansion for regular assignment into arrays which is why this works.

c(:) = {'ahola'}
c = 
    'ahola'    'ahola'    'ahola'

How else might we populate all the cells in c? One way is to use the function deal. I prefer the line above; I think the code without deal is clearer and it doesn't have the extra function call overhead.

[c{:}] = deal('ola')
c = 
    'ola'    'ola'    'ola'

If I have the values I want to store in the contents of c in another cell array, let's say d, I can again use deal but I don't have to. Compare the following 2 statements.

[c{:}] = deal(d{:})
[c{:}] = d{:}
c = 
    'hi'    [17]    [3.1416]
c = 
    'hi'    [17]    [3.1416]

In the first of these, I expand the cell array on the right to a comma-separated list and pass it through the function deal which then distributes the outputs into c. In the second statement, I bypass the function call to deal with some relatively new (MATLAB 7) syntax.

Now Explore structs

Let's do a similar exercise with structs now.

s = struct('f',a);
s.f
ans =
     1
ans =
     8     1     6
     3     5     7
     4     9     2
ans =
hello
try
    [s.f] = 'bonjour'; % error unless s is a scalar
catch structE
    disp(structE.message)
end
Too many output arguments.
[s.f] = deal('hej');
s.f
ans =
hej
ans =
hej
ans =
hej
[s.f] = d{:};
s.f
ans =
hi
ans =
    17
ans =
    3.1416

As you can see, I can bypass the function deal when assigning to a struct array in analogous way to cell array assignment.

References

Here are some prime references for getting more details on today's topic.

Why Do You Use deal?

I'd like to hear from you about situations where you feel using deal is your only option or you prefer it (perhaps readability?) to the no deal syntax. Let me know here.


Get the MATLAB code

Published with MATLAB® 7.5

8 Responses to “Deal or No Deal”

  1. Markus replied on :

    Say you have some struct containing names and phone numbers:

    s = struct(’name’, {}, ‘phone’, {})

    Then you can assign names to some fields in one line:

    [s(1:3).name] = deal(’Loren’, ‘Doug’, ‘Steve’);

    Without using deal, you would have to create a cell array and then assign:

    c = {’Loren’, ‘Doug’, ‘Steve’};
    [s(1:3).name] = c{:};

    In this case the use of deal allows more compact code.

    Markus

  2. Dan K replied on :

    Loren,
    I have always puzzled over the [c{:}] notation on the left hand side, but I think I may have had an epiphany. Is the reason for that notation that it is a shorthand form of the same method used for returning multiple outputs from a function? In short, is it simply the short form of writing:
    [c{1}, c{2}, c{3}]? I guess what this question is really indicating is I’m not sure *exactly* what square brackets mean on the left hand side of an expression. On the right hand side, it’s not problem: “concatenate these inputs into a new array.” But that doesn’t really hold for the left hand side, I think. Can you give the english statement which left hand side brackets is equivalent to?

    Thanks,
    Dan

  3. Omid replied on :

    Loren,
    I’m wondering why this works,

    [b{1:3}]=deal(1,2,3);
    [a{1:3}]=b{:};

    while this doesn’t,

    [a{:}]=1,2,3;
    ??? Too many output arguments.

    As far as I know, 1,2,3 is a comma-separated list too –dare I say just as good as b{:}? So why shouldn’t the latter work just as the former does?
    And actually, executing either

    b{:}

    or

    1,2,3

    gives the same output as one would expect,

    ans =
    1
    ans =
    2
    ans =
    3

    What is it that I’m missing here?

    -Omid

  4. Oliver A. Chapman, P.E. replied on :

    Loren,

    This is an important topic. But, I’m stumbling over the first part of the example.

    After your first example, the one that failed & generated an error, you say, “. . . because c is a cell array of length 3 and I used the comma-separated list notion.”

    Where is the comma-separated list notion? ‘aloha’ doesn’t look like a comma-separated list to my eye. I can’t find this term defined in the MatLab documentation, yet there are several pages of documentation regarding comma-separated lists. This appears to be a key concept that is well understood by MatLab developers, but not me.

    Although I can see that the failed syntax enclosed the target variable with the square brackets, I don’t understand the significance of the square brackets.

    Further, when I compare the failed syntax with the one without the square brackets, that didn’t generate an error, they seem very similar.

    Maybe the key question is, “How does the square brackets syntax interact with lists of comma-separated lists when the square bracket are used on the assignment side of the equals sign?”

    Thanks.

  5. Iain replied on :

    I have used deal when creating lambda functions that generate more than one output:

    @(x) deal(fn1(x), fn2(x))

    Actually, for this purpose I quickly swapped to using this version of deal:

    function varargout = mydeal(varargin)
    varargout = varargin(1:max(1,nargout));

    I wanted to create functions that behave like normal Matlab functions. That is, any outputs that aren’t asked for are silently discarded. Matlab’s deal throws an error if I do:

    fn = @(x) deal(x, 2*x); y = fn(2);

    So I use mydeal instead.

  6. Eric M. replied on :

    I try to avoid the deal function if at all possible. I have found that it can be much slower than using the commma seperated list notion.

  7. Loren replied on :

    Folks-

    Thanks for all the great comments. I think Markus and Iain have both pointed out times when using deal (or a doctored version) make sense.

    Dan, you are exactly right about what [] mean on the left side. It is the way MATLAB allows you to return more than one output and is not concatenation like it is when appearing on the right hand side. The comma-separated list c{1},c{2},c{3} is 3 outputs for MATLAB since each cell in a cell array is basically its own variable (though associated with all others in the same cell array). So [c{:}] builds up that list for you and allows you to return multiple left-hand sides from functions.

    Omid-
    MATLAB treats the physically appearance of , or ; or a newline as a line terminator. So 1,2,3 is 3 separate statements in MATLAB. However, the construct b{:} is treated as an entity unto itself, and allows concatenation into a regular or cell array when placed between [] or {}.

    Oliver-
    The comma-separated list referred to in that statement was for the left-hand side [c{:}] and not to ‘aloha’ which is a simple string value. The [] on the left allows me to assemble a list of output variables. And the c{:} in between builds the list c{1},c{2},c{3}.

    –Loren

  8. Oleg T. replied on :

    Hello, Loren and everyone.

    Deal is for sure a powerful tool, but the most frequent way I use deal is to swap values:
    [b,a] = deal(a,b);

Leave a Reply


Loren Shure works on design of the MATLAB language at The MathWorks. She writes here about once a week on MATLAB programming and related topics.

  • Ljubomir Josifovski: I have a simple figure where the legend overlaps with the plot after it is created, but when...
  • Hoi: Hi Peter, I’m glad to hear that you guys have plans to improve the compiler quality. Quality-wise, I think...
  • Peter Webb: Hoi, Long-term, we certainly plan on further improving the quality of the MATLAB Compiler (and all of the...
  • Peter Webb: GALLOU, I think the information in comment #9 might help you as well. If you compile using -C, and place...
  • Peter Perkins: Jasmine, I’m not exactly sure of the situation that you’re describing. There’s no...
  • jasmine: Hi Loren, I am trying to store both numerical and categorical values to a dataset array. As the data size is...
  • GALLOU: Hi, We have some need about a deployement process. We have a application which is compiled by MatLab Compiler...
  • Hoi: With -C switch, I think ctfroot will be the cleanest solution as the root path. Thanks Peter! Even with the -C...
  • Peter Webb: Hoi and Gunnar, You can exercise more control over where the encrypted files are installed via the...
  • Steve L: Ol, What Dave said is true, the constructor and set functions must be included inside the classdef file, but...

These postings are the author's and don't necessarily represent the opinions of The MathWorks.

Related Topics