目录
什么是逗号分隔的列表?
键入一系列逗号分隔的数字,即为所谓的逗号分隔的列表。MATLAB® 逐一返回每个值:
1,2,3
ans =
1
ans =
2
ans =
3
此类列表本身并不是非常有用。但是,当与更复杂的大型数据结构体(如 MATLAB 结构体)和元胞数组一起使用时,逗号分隔的列表能够帮助您简化 MATLAB 代码。
生成逗号分隔的列表
此部分介绍如何从元胞数组或 MATLAB 结构体生成逗号分隔的列表。
从元胞数组生成列表
从元胞数组提取多个元素即可得到一个逗号分隔的列表。以下面所示的 4×6 元胞数组为例
C = cell(4,6);
for k = 1:24
C{k} = k*2;
end
C
C =
[2] [10] [18] [26] [34] [42]
[4] [12] [20] [28] [36] [44]
[6] [14] [22] [30] [38] [46]
[8] [16] [24] [32] [40] [48]
提取第五列将生成以下逗号分隔的列表:
C{:,5}
ans =
34
ans =
36
ans =
38
ans =
40
这一结果与显式键入以下内容所得到的列表相同
C{1,5},C{2,5},C{3,5},C{4,5}
从结构体生成列表
对于结构体,提取结构体在某一维度上存在的字段即可得到一个逗号分隔的列表。
首先将前面使用的元胞数组转换为一个带有六个字段的 4×1 MATLAB 结构体,这六个字段为:
f1
到
f6
。读取所有行的字段
f5
,MATLAB 会返回一个字段分隔的列表:
S = cell2struct(C,{'f1','f2','f3','f4','f5','f6'},2);
S.f5
ans =
34
ans =
36
ans =
38
ans =
40
这一结果与显式键入以下内容所得到的列表相同
S(1).f5,S(2).f5,S(3).f5,S(4).f5
从逗号分隔的列表分配输出
可以通过一个简单的赋值语句将逗号分隔列表的任何或所有连续元素分配给变量。使用前一部分中的元胞数组
C
,将第一行分配给
c1
到
c6
变量:
C = cell(4,6);
for k = 1:24
C{k} = k*2;
end
[c1,c2,c3,c4,c5,c6] = C{1,1:6};
c5
c5 =
34
如果指定的输出变量的数目少于表达式返回的输出数目,MATLAB 会将前 N 个输出分配给 N 个变量,然后放弃其余的任何输出。在接下来的示例中,MATLAB 将 C{1,1:3} 分配给变量 c1、c2 和 c3,然后放弃 C{1,4:6}:
[c1,c2,c3] = C{1,1:6};
可以按照相同的方式分配结构体输出:
S = cell2struct(C,{'f1','f2','f3','f4','f5','f6'},2);
[sf1,sf2,sf3] = S.f5;
sf3
sf3 =
38
此外,也可以使用deal函数来实现此目的。
为逗号分隔的列表赋值
将多个值分配给逗号分隔的列表的最简单方法是使用deal函数。此函数将其所有输入参数分发给逗号分隔的列表的元素。
此示例使用
deal
覆盖逗号分隔的列表中的每个元素。首先创建一个列表。
c{1} = [31 07];
c{2} = [03 78];
c{:}
ans =
31 7
ans =
3 78
使用
deal
覆盖列表中的每个元素。
[c{:}] = deal([10 20],[14 12]);
c{:}
ans =
10 20
ans =
14 12
以下示例与上述示例执行相同的操作,不同的是将值赋给了结构体字段中以逗号分隔的向量列表:
s(1).field1 = [31 07];
s(2).field1 = [03 78];
s.field1
ans =
31 7
ans =
3 78
使用
deal
覆盖结构体字段。
[s.field1] = deal([10 20],[14 12]);
s.field1
ans =
10 20
ans =
14 12
如何使用逗号分隔的列表
-
构造数组
-
显示数组
-
串联
-
用作函数调用参数
-
用作函数返回值
以下部分提供了将逗号分隔的列表与元胞数组一起使用的示例。其中每个示例也适用于 MATLAB 结构体。
构造数组
构造矩阵或数组时,可以使用逗号分隔的列表来输入一组元素。请注意当插入元素列表而不是添加元胞本身时会发生什么情况。
当使用
C{:, 5}
指定元素列表时,MATLAB 将会插入四个单独的元素:
A = {'Hello',C{:,5},magic(4)}
A =
'Hello' [34] [36] [38] [40] [4x4 double]
当指定C元胞本身时,MATLAB将会插入整个元胞数组:
A = {'Hello',C,magic(4)}
A =
'Hello' {4x6 cell} [4x4 double]
显示数组
A{:}
ans =
Hello
ans =
[2] [10] [18] [26] [34] [42]
[4] [12] [20] [28] [36] [44]
[6] [14] [22] [30] [38] [46]
[8] [16] [24] [32] [40] [48]
ans =
16 2 3 13
5 11 10 8
9 7 6 12
4 14 15 1
串联
将逗号分隔的列表放在方括号内,可从列表中提取指定的元素并将这些元素进行串联:
A = [C{:,5:6}]
A =
34 36 38 40 42 44 46 48
用作函数调用参数
编写函数调用代码时,可以列表形式输入各输入参数,并将每个参数用逗号进行分隔。如果将这些参数存储在某个结构体或元胞数组中,则可以从该结构体或元胞数组生成整个或部分参数列表。传入数量可变的参数时,这会特别有用。
以下示例将多个属性-值参数传递给plot函数:
X = -pi:pi/10:pi;
Y = tan(sin(X)) - sin(tan(X));
C = cell(2,3);
C{1,1} = 'LineWidth';
C{2,1} = 2;
C{1,2} = 'MarkerEdgeColor';
C{2,2} = 'k';
C{1,3} = 'MarkerFaceColor';
C{2,3} = 'g';
figure
plot(X,Y,'--rs',C{:})
用作函数返回值
MATLAB 函数也可以向调用方返回多个值。这些值以列表形式返回,并且每个值用逗号分隔。可以将逗号分隔的列表与结构体或元胞数组一起使用,而不用列出每个返回值。对于返回值的数量可变的函数,这一用法更为实用。
以下示例向一个元胞数组返回三个值:
C = cell(1,3);
[C{:}] = fileparts('work/mytests/strArrays.mat')
C =
'work/mytests' 'strArrays' '.mat'
快速傅里叶变换示例
fftshift函数交换数组的每个维度的左半部分和右半部分。对于简单向量(例如 [0 2 4 6 8 10]),输出将为 [6 8 10 0 2 4]。对于多维数组,fftshift 沿每个维度执行此交换。
fftshift 使用索引向量来执行交换。对于上面显示的向量,索引 [1 2 3 4 5 6] 经过重新排列以形成新索引 [4 5 6 1 2 3]。然后,该函数使用此索引向量重新定位各元素。对于多维数组,fftshift 必须为每个维度构造一个索引向量。逗号分隔的列表使该任务变得很简单。
function y = fftshift(x)
numDims = ndims(x);
idx = cell(1,numDims);
for k = 1:numDims
m = size(x,k);
p = ceil(m/2);
idx{k} = [p+1:m 1:p];
end
y = x(idx{:});
end
该函数将索引向量存储在元胞数组 idx 中。构建此元胞数组相对比较简单。对于 N 维中的每个维度,请确定该维度的大小并计算最接近中点的整数索引。然后,构造一个交换该维度左右部分的向量。
通过使用元胞数组存储索引向量以及使用逗号分隔的列表进行索引运算,fftshift只需执行单个运算y = x(idx{:}) 即可移动任意维度的数组。如果要使用显式索引,则需要为希望函数处理的每个维度都编写一条if语句:
if ndims(x) == 1
y = x(index1);
else if ndims(x) == 2
y = x(index1,index2);
end
end
在没有逗号分隔的列表时处理这种情况的另一种方法是对每个维度进行循环,每次转换一个维度并移动数据。通过逗号分隔的列表,只需将数据移动一次。逗号分隔的列表使得将交换运算推广到任意数量的维度变得非常容易。