在访问(A)数组,(B)单元格或(C)结构的元素时,我有一个关于for循环语法的相当普遍的问题我希望迭代:
何时(以及如何)可以访问我想要迭代的数据中的元素而不进行索引?或者相反:我何时必须使用索引来访问数据,因为只能通过访问迭代变量是不可能的?
通过迭代变量访问我的意思有望通过以下示例得到明确。
(A)数组(或“矩阵”)
array = [2 4 6 8 10];
for i = 1:length(array) % access with index
fprintf('%i |', array(i)); % is less elegant than ...
end
for number = array % access with iteration variable
fprintf('%i |', number);
end
这适用于一维数据和二维数据,我们可以在不进行索引的情况下访问二维数组的向量:
array_2d = [ [2;4] [22;44] [222;444] ];
for vector = array_2d % access with iteration variable
fprintf('%s |', mat2str(vector));
end
但是我还没想出如何在更高的尺寸上做到这一点。假设我们在阵列中有五个8x8图像,并希望逐个访问它们。显然使用索引是有效的,但尝试像for image = array_3d
这样的东西会给出向量(与2d情况相同的行为,只有在这里我们想要别的东西):
array_3d = rand([8,8,5]); % e.g. five 8x8 images
for i = 1:size(array_3d, 3); % access with index in 3rd dim
image = array_3d(:,:,i); % assigning to a new variable is sometimes required
% since array_3d(:,:,i)(end) isnt allowed
last_pixel = image(end); % e.g. to get the last pixel of the image
all_pixels = image(:); % ... or all elements of the image matrix
fprintf('%s |\n', mat2str(image));
end
% access with iteration variable does not work as intended:
% it will give 5*8 times a 8x1 vector
for image = array_3d;
fprintf('%s |', mat2str(image));
end
我在这里错过了一些语法糖吗?有没有办法通过迭代变量方便地访问数组的部分,还是仅限于数字/向量? 或者重构:是否有可能在没有索引的情况下使用for循环对矩阵进行切片(我认为这就是所谓的)?
(B)CELL
对于单元格,索引后使用(end)
或(:)
等运算符的限制不适用,因为cellArray{i}(end)
有效。这很好,因为我只找到了与索引配合使用的解决方案:
cellArray = cell(1, 3);
cellArray(1:3) = {rand(8,8)};
% create idx from length()
for i = 1:length(cellArray) % access with index
cellContent = cellArray{i};
% ... do stuff with cellContent
end
for cell = cellArray % access with iteration variable possible
% BUT cellContent is wrapped in 1x1 cell and needs to be accessed (with) trivial index
cellContent = cell{1};
% still this allows to do things like:
last_pixel = cell{1}(end);
end
并不是说它会改变任何东西,只会让代码变得更漂亮,但我仍然很好奇是否有可能没有......
(C)STRUCT
在我看来,最优雅的访问权限在于结构“对象”。
structContent1 = num2cell(1:10);
[myStruct(1:10).idx] = structContent1{:};
structContent2(1:10) = {rand(8,8)};
[myStruct(1:10).img] = structContent2{:};
for strctObj = myStruct % access with iteration variable
fprintf('%i |\n', strctObj.idx);
fprintf('%s |\n', mat2str(strctObj.img));
all_pixels = strctObj.img(:); % ... or all elements of the image matrix
end
但是,只迭代一个字段需要与使用单元格数组时相同的“解决方法”:
for image = {myStruct.img} % access with iteration variable possible
% BUT needs to be accessed with {1} workaround (see cell access)
fprintf('%s |\n', mat2str(image{1}));
all_pixels = image{1}(:); % ... or all elements of the image matrix
end
所以基本上我在问:有没有办法放弃for循环中的索引访问? 我想我只是出于好奇而要求更多的对象面向感觉和更漂亮的代码。