元胞数组 #

一、元胞数组概述 #

元胞数组(cell array)是一种特殊数组,每个元素(称为元胞)可以存储不同类型的数据:

matlab
% 创建元胞数组
C = {'Hello', 123, [1 2 3], struct('name', '张三')};

% 查看内容
C
% C = 
%     1×4 cell array
%     {'Hello'}    {[123]}    {[1 2 3]}    {1×1 struct}

二、创建元胞数组 #

2.1 使用花括号 #

matlab
% 行向量
C = {'Hello', 123, [1 2 3]};

% 多维数组
C = {'Hello', 123; 'World', 456};

% 空元胞数组
empty_cell = {};

2.2 使用cell函数 #

matlab
% 创建空元胞数组
C = cell(3, 3);    % 3×3空元胞数组

% 创建指定大小
C = cell(2, 3);    % 2×3空元胞数组
C = cell(4);       % 4×4空元胞数组

2.3 元胞数组赋值 #

matlab
% 预分配后赋值
C = cell(1, 3);
C{1} = 'Hello';
C{2} = 123;
C{3} = [1 2 3];

% 混合赋值
C{1, 1} = 'Name';
C{1, 2} = 'Age';
C{2, 1} = '张三';
C{2, 2} = 20;

三、访问元胞数组 #

3.1 花括号访问(获取内容) #

matlab
C = {'Hello', 123, [1 2 3; 4 5 6]};

% 获取元胞内容
str = C{1};       % 'Hello'
num = C{2};       % 123
mat = C{3};       % [1 2 3; 4 5 6]

% 访问内容的一部分
val = C{3}(1, 2); % 2

3.2 圆括号访问(获取元胞) #

matlab
C = {'Hello', 123, [1 2 3]};

% 获取元胞本身(仍是cell类型)
cell1 = C(1);     % {'Hello'}
cell2 = C(2);     % {[123]}

% 检查类型
class(C{1})       % 'char'
class(C(1))       % 'cell'

3.3 多元素访问 #

matlab
C = {'a', 'b', 'c', 'd', 'e'};

% 获取多个元胞
cells = C(1:3);   % {'a', 'b', 'c'}

% 获取多个内容
contents = C{1:3};  % 只返回第一个内容 'a'

% 正确方式:使用cell2mat或循环
contents = C(1:3);
strs = cell2mat(contents);  % 'abc'

四、元胞数组操作 #

4.1 添加元素 #

matlab
C = {'Hello', 123};

% 添加到末尾
C{3} = [1 2 3];
C{end+1} = 'World';

% 添加到指定位置
C{1, 4} = 'New';

4.2 删除元素 #

matlab
C = {'a', 'b', 'c', 'd'};

% 删除单个元素
C(2) = [];        % {'a', 'c', 'd'}

% 删除多个元素
C([1 3]) = [];    % {'c'}

% 清空元胞内容(保留位置)
C{1} = [];        % {[], 'c'}

4.3 连接元胞数组 #

matlab
C1 = {'a', 'b'};
C2 = {'c', 'd'};

% 水平连接
C = [C1, C2];     % {'a', 'b', 'c', 'd'}

% 垂直连接
C = [C1; C2];     % {'a', 'b'}
                    % {'c', 'd'}

% 使用cat
C = cat(1, C1, C2);  % 垂直
C = cat(2, C1, C2);  % 水平

4.4 转置和重塑 #

matlab
C = {'a', 'b', 'c', 'd', 'e', 'f'};

% 转置
C_t = C';         % 列向量

% 重塑
C_mat = reshape(C, 2, 3);
% {'a', 'c', 'e'}
% {'b', 'd', 'f'}

五、元胞数组函数 #

5.1 类型转换 #

matlab
% 元胞数组转矩阵
C = {1 2 3; 4 5 6};
M = cell2mat(C);  % [1 2 3; 4 5 6]

% 矩阵转元胞数组
M = [1 2 3; 4 5 6];
C = mat2cell(M, [1 1], [1 2 1]);
% {[1]}    {[2 3]}    {[4]}
% {[4]}    {[5 6]}    {[6]}

% num2cell
M = [1 2 3; 4 5 6];
C = num2cell(M);
% {[1]}    {[2]}    {[3]}
% {[4]}    {[5]}    {[6]}

5.2 字符串处理 #

matlab
% 字符串元胞数组
strs = {'Hello', 'World', 'MATLAB'};

% 连接字符串
result = strjoin(strs, ' ');  % 'Hello World MATLAB'

% 分割字符串
str = 'a,b,c,d';
parts = strsplit(str, ',');   % {'a', 'b', 'c', 'd'}

% 字符串比较
strcmp('Hello', 'World')      % 0
strcmpi('Hello', 'HELLO')     % 1

5.3 查找和筛选 #

matlab
C = {'apple', 123, 'banana', 456, 'cherry'};

% 查找字符串
idx = find(cellfun(@ischar, C));  % [1, 3, 5]

% 筛选字符串
strings = C(cellfun(@ischar, C));  % {'apple', 'banana', 'cherry'}

% 筛选数值
numbers = C(cellfun(@isnumeric, C));  % {123, 456}

5.4 cellfun函数 #

matlab
C = {'Hello', 'World', 'MATLAB'};

% 计算每个字符串长度
lengths = cellfun(@length, C);  % [5, 5, 6]

% 转换为大写
upper_strs = cellfun(@upper, C, 'UniformOutput', false);
% {'HELLO', 'WORLD', 'MATLAB'}

% 自定义函数
C = {1, 2, 3, 4, 5};
squares = cellfun(@(x) x^2, C);  % [1, 4, 9, 16, 25]

% 多输出
C = {'Hello', 'World'};
[first, last] = cellfun(@(s) [s(1), s(end)], C);
% first = ['H', 'W']
% last = ['o', 'd']

六、元胞数组与结构体 #

6.1 结构体转元胞数组 #

matlab
student.name = '张三';
student.age = 20;
student.scores = [85 90 78];

% 转为元胞数组
C = struct2cell(student);
% {'张三'}
% {20}
% {[85 90 78]}

% 获取字段名
fields = fieldnames(student);
% {'name'; 'age'; 'scores'}

6.2 元胞数组转结构体 #

matlab
% 元胞数组转结构体
values = {'张三', 20, [85 90 78]};
fields = {'name', 'age', 'scores'};

student = cell2struct(values, fields, 2);
% student = 
%     name: '张三'
%      age: 20
%   scores: [85 90 78]

七、实用示例 #

7.1 存储混合数据 #

matlab
% 存储不同类型的数据
data{1} = '实验数据';
data{2} = datetime('2024-03-27');
data{3} = rand(100, 5);
data{4} = struct('name', '实验1', 'type', '温度测试');
data{5} = {'样本1', '样本2', '样本3'};

% 访问数据
exp_name = data{1};
exp_date = data{2};
measurements = data{3};
exp_info = data{4};
samples = data{5};

7.2 处理变长数据 #

matlab
% 存储不同长度的向量
data{1} = [1 2 3];
data{2} = [4 5 6 7 8];
data{3} = [9 10];

% 计算每个向量的平均值
averages = cellfun(@mean, data);  % [2, 6, 9.5]

% 合并数据
all_data = cell2mat(data');  % [1 2 3 4 5 6 7 8 9 10]

7.3 表格数据处理 #

matlab
% 创建表格数据
headers = {'Name', 'Age', 'Score'};
row1 = {'张三', 20, 85};
row2 = {'李四', 22, 90};
row3 = {'王五', 21, 78};

% 存储为元胞数组
table_data = [headers; row1; row2; row3];

% 转换为table
T = cell2table(table_data(2:end, :), 'VariableNames', headers);

7.4 函数参数传递 #

matlab
% 使用元胞数组传递可变参数
function result = process_data(data, varargin)
    % varargin是元胞数组
    for i = 1:length(varargin)
        param = varargin{i};
        fprintf('参数%d: ', i);
        disp(param);
    end
end

% 调用
process_data(data, 'method', 'linear', 'tolerance', 1e-6);

八、元胞数组 vs 其他类型 #

8.1 与矩阵对比 #

matlab
% 矩阵:同类型数据
M = [1 2 3; 4 5 6];    % 只能存储数值

% 元胞数组:混合类型
C = {1, 'hello', [1 2 3]};  % 可存储不同类型

% 选择:
% - 同类型数据用矩阵(效率高)
% - 混合类型数据用元胞数组

8.2 与结构体对比 #

matlab
% 结构体:有命名字段
student.name = '张三';
student.age = 20;

% 元胞数组:无命名字段
student = {'张三', 20};

% 选择:
% - 需要字段名用结构体
% - 简单数据集合用元胞数组

8.3 与string数组对比 #

matlab
% string数组:只能存储字符串
strs = ["Hello", "World"];

% 元胞数组:可存储字符串和其他类型
C = {'Hello', 123, 'World'};

% 选择:
% - 纯字符串用string数组
% - 混合类型用元胞数组

九、常见错误 #

9.1 访问方式混淆 #

matlab
C = {'Hello', 123};

% 错误:混淆()和{}
% C(1) 返回 {'Hello'}(cell类型)
% C{1} 返回 'Hello'(char类型)

% 常见错误
% str = C(1);  % str是cell,不是字符串
% upper(str);  % 错误!

% 正确方式
str = C{1};    % 获取字符串内容
upper(str);    % 'HELLO'

9.2 类型不匹配 #

matlab
C = {'a', 'b', 'c'};

% 错误:尝试数值运算
% sum(C);  % 错误!

% 正确方式
lengths = cellfun(@length, C);
sum(lengths);  % 3

9.3 空元胞处理 #

matlab
C = cell(1, 3);
% C = {[], [], []}

% 检查空元胞
isempty(C{1})  % true

% 删除空元胞
C(cellfun(@isempty, C)) = [];

十、最佳实践 #

10.1 预分配元胞数组 #

matlab
% 不推荐:动态扩展
C = {};
for i = 1:1000
    C{i} = rand();
end

% 推荐:预分配
C = cell(1, 1000);
for i = 1:1000
    C{i} = rand();
end

10.2 使用cellfun提高效率 #

matlab
C = {'apple', 'banana', 'cherry'};

% 不推荐:循环
lengths = zeros(1, length(C));
for i = 1:length(C)
    lengths(i) = length(C{i});
end

% 推荐:cellfun
lengths = cellfun(@length, C);

10.3 合理选择数据类型 #

matlab
% 纯数值数据:使用矩阵
data = [1 2 3; 4 5 6];

% 纯字符串数据:使用string数组
names = ["张三", "李四", "王五"];

% 混合类型数据:使用元胞数组或结构体
mixed = {'张三', 20, [85 90 78]};
student.name = '张三';
student.age = 20;
student.scores = [85 90 78];

十一、总结 #

本章学习了:

  1. 创建元胞数组:花括号、cell函数
  2. 访问方式:花括号获取内容、圆括号获取元胞
  3. 元胞数组操作:添加、删除、连接、重塑
  4. 类型转换:cell2mat、mat2cell、num2cell
  5. cellfun函数:对每个元胞应用函数
  6. 与结构体转换:struct2cell、cell2struct
  7. 实用技巧:存储混合数据、处理变长数据

下一章将学习MATLAB的数组与矩阵操作。

最后更新:2026-03-27