Why does cell2mat convert a cell array into a matrix of characters, instead of a matrix of cell contents?

889 Views Asked by At

I have this cell array

>> FooCellArray

FooCellArray =

  1×7 cell array

  Columns 1 through 4

    {'Foo1'}    {'Foo2'}    {'Foo3'}    {'Foo4'}

  Columns 5 through 7

    {'Foo5'}    {'Foo6'}    {'Foo7'}

cell2mat() converts the array into a character array instead of a 1x7 or 7x1 matrix of 'Foo1' ... 'Foo7'.

>> (cell2mat(FooCellArray))'

ans =

  28×1 char array

    'F'
    'o'
    'o'
    '1'
    'F'
    'o'
    'o'
    '2'
    'F'
    'o'
    'o'
    '3'
    'F'
    'o'
    'o'
    '4'
    ....

Why?

2

There are 2 best solutions below

0
Edric On

cell2mat is doing precisely the correct thing as documented here. Each cell element is char vector of size 1xN. Your overall cell array is 1xN. cell2mat concatenates the contents of every cell in the "natural" direction as defined by the shape of the cell array. Your original cell looks a bit like this:

FooCellArray = [{'Foo1'}, {'Foo2'}]

The effect of cell2mat is basically as if you removed the {}, so you're left with

cell2mat(FooCellArray) --> ['Foo1', 'Foo2']

And therefore this gets concatenated into a single char vector 'Foo1Foo2'.

Compare with vectors of double instead of vectors of char:

>> FooCellArray = [{[1,2,3]}, {[4,5,6]}]
FooCellArray =
  1×2 cell array
    {[1 2 3]}    {[4 5 6]}
>> cell2mat(FooCellArray)
ans =
     1     2     3     4     5     6
0
Hoki On

With a smaller starting example:

FooCellArray = {'Foo1','Foo2','Foo3'} ;

If your MATLAB version is >= 2017b

You can directly use the function convertCharsToStrings:

>> convertCharsToStrings(FooCellArray)
ans = 
  1×3 string array
    "Foo1"    "Foo2"    "Foo3"

The benefit of this method is that it will work even if the strings contained in your cell array are not all of the same length. You can transpose it if you want it as a column instead of line vector. Note the terminology of the result type, it is a string array.


If you MATLAB version is older AND if all the strings in the cell array have the same length, you could convert your cell array into a 2D character array:

>> reshape(cell2mat(FooCellArray),4,[]).'
ans =
  3×4 char array
    'Foo1'
    'Foo2'
    'Foo3'

For this one, transposition wouldn't really make sense. This result type is a char array, which are ok when they are simple vector but they get quite unwieldy once they are in 2D. Mainly because they are not as flexible as strings, each line has to have the same number of elements. So as @Adriaan pointed at, if one of your cell contained Foo24 then the reshape command would error.

Edit: Or as Chris Luengo kindly mentionned in comment, a simpler command to get exactly the same result:

>> cell2mat(FooCellArray.')
ans =
  3×4 char array
    'Foo1'
    'Foo2'
    'Foo3'

This has the same restriction, all the cell contents must have the same number of characters or the command will error.