什么是元胞数组
前面咱们介绍过矩阵的概念,但是矩阵有一个缺陷,它只能存储同一种类型的数据。同一个矩阵中,要么都是数字,要么就都是字符串。元胞数组 ( Cell Array ) 就可以解决这个问题。
这里插播一个问题:一会儿说矩阵一会儿又说数组的,这两个是一回事吗?
严格意义上,数组比矩阵的概念外延更大一些。矩阵单纯由数字元素构成,而数组不仅可以是数字元素,也可以是字符元素。
在前面,我已经混着用了,所以,将错就错下去了,不再区分这两个概念。
回到正题。类似于矩阵的概念,元胞数组也是由多个 “ 元胞 ” ( cell )数据排排座构成的。元胞是一种比较特殊的东西,它可以保存任意一种类型的数据。这样一来,元胞数组就成了一种可以包含各种类型和大小的数据的数组。
在上一篇教程里面我们用 xlsread
函数读了一个 excel 表格。其中,返回值 raw
的结果如下:
raw =
4×3 cell 数组
{'标题1'} {'标题2'} {'标题3'}
{[ 11]} {[ 21]} {[ 31]}
{[ 12]} {[ 22]} {[ 32]}
{[ 13]} {[ 23]} {[ 33]}
它原样照搬了 excel 表格中的内容,但是表格里的数据有两种类型:标题是字符串的,而每列下面的内容却又是数字的。如果你用创建矩阵的写法来写这样的数据是会报错的。试试看:
>> a = ['标题1', '标题2', '标题3';11, 21, 31]
串联的矩阵的维度不一致。
有关 “ 串联矩阵的维度不一致的问题 ” 大家还可以自己试试下面这些例子:
>> ['hello', 'world']
ans =
'helloworld'
>> ['hello'; 'world']
ans =
2×5 char 数组
'hello'
'world'
>> ['hello'; 'world !']
串联的矩阵的维度不一致。
>> ['hello', 'world !']
ans =
'helloworld !'
通过这些例子,大家仔细体会一下下面的逻辑:
一个矩阵对元素的数据类型与大小有限制,但是元胞数组没有这种限制。
对元胞数组的理解,需要了解两个东西:首先,一个元胞可以保存任意类型与大小的数据;其次,元胞数组是多个元胞组成的矩阵,因此,元胞数组就成了一个可以保存各种类型和大小的数据的数组。
元胞数组的创建与引用
元胞数组的创建
类似于使用 [ ]
运算符创建矩阵的方法,使用 { }
创建元胞数组。示例:
>> data = {'name', 'gender', 'score'; 'John', 'male', 98}
data =
2×3 cell 数组
{'name'} {'gender'} {'score'}
{'John'} {'male' } {[ 98]}
引用元胞数组中的元素
在这里先要搞清楚要引用的是元胞还是元胞中的数据,不然在下面涉及到 ( )
和 { }
的时候会晕菜 。
前面说过,元胞数组就是由元胞构成的矩阵。在上面的例子中,命令行中显示的结果中, data 是由六个 { }
括起来的数据构成。这六个 { }
括起来的数据是元胞。引用元胞数组的元胞时采用 ( )
运算符。 例如,取元胞数组 data 的第二行所有列数据:
>> data(2, :)
ans =
1×3 cell 数组
{'John'} {'male'} {[98]}
取第二行第二列的元胞:
>> data(2,2)
ans =
1×1 cell 数组
{'male'}
请注意,到目前为止,所获得的数据仍然是元胞数组。
再往前走一步,每个 { }
括起来的数据,是元胞里面的数据。例如,字符串 name
是 data 中第一个元胞的数据内容;98
是 data 中最后一个元胞里的内容。 访问元胞中的内容时,使用{ }
运算符。例如,取第二行所有元胞中的数据:
>> data{2, :}
ans =
'John'
ans =
'male'
ans =
98
这里,我们没有将这三个数据分别赋值,Matlab 自动使用 ans 变量接受数据。请注意,这时候取到的值是字符串或数字。
如果我们希望将这三个数值都保存下来,可以设定三个变量分别接受这三个数据,如:
>> [a, b, c] = data{2, :};
请仔细体会元胞与元胞中的内容二者的区别,能正确区分使用 { }
与 ( )
运算符。
元胞数组的元胞添加、删除与合并操作
与矩阵元素添加、删除及合并操作类似,只是运算符号变成了{ }
, 分别举例说明。
添加元胞至元胞数组:
>> data = {1,2,3}
data =
1×3 cell 数组
{[1]} {[2]} {[3]}
>> data(4) = {4}
data =
1×4 cell 数组
{[1]} {[2]} {[3]} {[4]}
元胞数组的删除操作有两类:
一种是删除元胞数组某个元胞中的内容:
>> data{3} = []
data =
1×4 cell 数组
{[1]} {[2]} {0×0 double} {[4]}
另一种是删除元胞数组中的某个元胞:
>> data(3) = []
data =
1×3 cell 数组
{[1]} {[2]} {[4]}
请结合前面介绍的 { }
与 ( )
的区别,仔细体会上面的两句代码。
合并元胞数组:
先创建三个元胞数组:
data1 = {1,2,3};
data2 = {'a', 'b', 'c'};
data3 = {4,5,6};
这三个数组都是 1X3 的元胞数组,如果我希望合并成一个 3X3 的元胞数组,应该采用数组运算符 [ ]
。
>> data = [ data1; data2; data3 ]
data =
3×3 cell 数组
{[1]} {[2]} {[3]}
{'a'} {'b'} {'c'}
{[4]} {[5]} {[6]}
可能有同学要晕菜了。
我们前面讲过创建一个矩阵(或者是数组)用 [ ]
运算符。请注意,元胞数组它本质上仍然是一个数组。将这三个元胞数组串联合并,应该是生成一个新的数组,只不过这个数组是由元胞构成。请结合教程中有关矩阵操作的那部分再琢磨下。
继续,现在我们希望将这三个元胞数组合并成一个 1X3 的元胞数组:
>> data_cell1 = {data1, data2, data3}
data_cell =
1×3 cell 数组
{1×3 cell} {1×3 cell} {1×3 cell}
这里 data_cell1 是一个 1X3 的元胞数组,每个元胞又是分别由 data1, data2, data3 这样的 1X3 元胞数组构成。
最后,再给出一个例子,请说明这样的数组是怎么构成的。
>> data_cell2 = {data1; data2; data3};
有关元胞数组的内容就更到这里了,有点小复杂,仔细琢磨下元胞数组、元胞以及元胞中的数据这三者的区别,就能正确使用 ( )
、[ ]
以及 { }
。