Search code examples
matlabcell-array

Matlab Array has strange syntax


In Matlab, we use textscan to get a cell array from a file or somewhere. But the behavior of the cell array is so strange. There is the sample code:

>> str = '0.41 8.24 3.57 6.24 9.27';
>> C = textscan(str, '%3.1f %*1d');
>> C

C = 

[5x1 double]

We can know that C is a cell array of size 5 * 1. When I use C{1}, C{1}{1} and C(1). I get the following result:

>> C{1}

ans =

0.4000
8.2000
3.5000
6.2000
9.2000

>> C{1}{1}
Cell contents reference from a non-cell array object.

>> C(1)

ans = 

[5x1 double]

Why I cannot use C{1}{1} to get the element from the cell array ? Then how can I get the elements from that cell array ?

An example I found on the Internet is :

%% First import the words from the text file into a cell array
fid = fopen(filename);

words = textscan(fid, '%s');

%% Get rid of all the characters that are not letters or numbers
for i=1:numel(words{1,1})
    ind = find(isstrprop(words{1,1}{i,1}, 'alphanum') == 0);
    words{1,1}{i,1}(ind)=[];
end

As words{1,1}{i,1}(ind)=[] show, what is the mechanism of using {}?

Thanks


Solution

  • There is a slightly different syntax for indexing into cell arrays and numerical arrays. Your output

    >> C
    C = 
    
    [5x1 double]
    

    is telling you that what you have is a 1x1 cell array, and in that 1 cell is a 5x1 array of doubles. Cell arrays are indexed into with {}, while 'normal' arrays are indexed into with ().

    So you want to index into the first element of the cell array, and then index down to the first value in the 5x1 array of doubles using C{1}(1). To get the second value - C{1}(2), and so forth.

    If you're familiar with other programming languages, cell arrays are something like arrays of pointers; the operator A(n) is used to get the nth element of the array A, while A{n} gets the object pointed to by the nth element of the array A (or 'contained in the nth cell of cell array A'). If A is not a cell array, A{n} fails.

    So, knowing that C is a cell array, here's why you got what you got in the cases you tried -

    C{1} returns the 5x1 double array contained in the first cell of C.

    C{1}{1} gets the object (call it B) contained in the first cell of C, and then tried to get the object contained in the first cell of B. It fails because B is not a cell array, it is a 5x1 double array.

    And C(1) returns the first element of C, which is a single cell containing a 5x1 double array.

    But C{1}(1) would get you the first element of the 5x1 array contained in the first cell of C, which is what you are looking for. As @Cheery above me noted, it's probably easier, instead of writing C{1}(1), C{1}(2), ... to remove the 'cell-level' indexing by setting C=C{1}, which means C is now a 5x1 double array, and you can get the elements of it using C(1), C(2), ... Hope that makes sense!