元胞数组 #
一、元胞数组概述 #
元胞数组(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];
十一、总结 #
本章学习了:
- 创建元胞数组:花括号、cell函数
- 访问方式:花括号获取内容、圆括号获取元胞
- 元胞数组操作:添加、删除、连接、重塑
- 类型转换:cell2mat、mat2cell、num2cell
- cellfun函数:对每个元胞应用函数
- 与结构体转换:struct2cell、cell2struct
- 实用技巧:存储混合数据、处理变长数据
下一章将学习MATLAB的数组与矩阵操作。
最后更新:2026-03-27