【问题标题】:Matlab: iterate over multiple structsMatlab:迭代多个结构
【发布时间】:2017-01-01 00:28:03
【问题描述】:

我有 5 个 Matlab 结构。我想遍历它们。我目前的解决方案如下:

all_structs = [struct1,struct2,struct3,struct4,struct5];
for single_struct = all_structs
    % do stuff to each struct here
end

但是,上面的每个结构都有一个包含大量数据(包括其他一些属性)的矩阵。另外,我在single_struct 中所做的任何更改都不会传递回原来的struct

问题:我该如何解决这个问题?当我创建向量all_structs 时,Matlab 是否会再次复制所有这些数据?还是每个结构(struct1,...,struct5)的数据是通过引用传递的?有没有更好的方法来迭代多个结构?

感谢您的帮助!

【问题讨论】:

  • 听起来好像最初的问题是结构不是结构数组。我会自发地建议您尝试解决原始问题。我知道这有时会很复杂,但否则我相信你必须忍受这种开销。如果你这样做一次,时间延迟不会那么糟糕。答案中有eval 的解决方案,但我不推荐它。如果内存失效,也可以分步进行。
  • @patrik 嘿,这是一个非常有用的建议。因此,与其创建一堆结构体,不如创建一个结构体数组,它就像一个包含结构体的结构体。是这样吗?
  • 就是这样完成的。这里值得注意的是,所有结构都将具有相同的字段,并且这些字段中的矩阵将具有相同的大小。 struct 元素可以完全作为数组访问,numel(s(1).a) == N; numel(s(2).a) == N。如果矩阵的大小不同,则必须改用 cell 数组。这些可通过运算符{}numel(c{1}) ==N; numel(c{2} ~=N) 访问。

标签: matlab for-loop struct


【解决方案1】:

struct 不会通过引用传递。您需要使用索引遍历all_structs 中的元素,然后使用该索引进行访问和修改。如果您需要将某些内容视为参考,则需要为其定义一个类并让该类继承自handleSuggested reading

for i = 1:numel(all_structs)
    % do stuff to each struct here
    all_structs(i).data = ones(10,5); % your code here
end

我建议您也阅读arrayfun,尽管如果您想进行操作并获得结果,这很有用。从您的描述看来,您想修改结构。

【讨论】:

  • 请记住,arrayfun 比单个 for 循环慢。
【解决方案2】:

如果您想修改原始结构的内容,而无需复制,您可以使用结构名称的元胞数组。
然后迭代名称,使用eval修改内容。
使用eval 效率低下,所以不要养成习惯...

参见以下代码示例:

%Create sample structs (each struct has a data element).
struct1.data = 1;
struct2.data = 2;
struct3.data = 3;

%Create a cell array containing structs names as strings.
struct_names = {'struct1', 'struct2', 'struct3'};

%Iterate all structs names
%Modify data elements of each struct using eval.
for i = 1:length(struct_names)
    sname = struct_names{i}; %Get struct name from cell array.

    %Evaluate a string like: 'struct1.data = struct1.data + 1;'
    eval([sname, '.data = ', sname, '.data + 1;']);
end

【讨论】:

  • “使用eval效率低下,所以不要养成习惯……”为什么要推荐坏习惯?
  • @EBH 在某些情况下,使用 eval 是最好的选择。当给定结构时(首先不是在数组中),使用 eval 看起来比创建结构数组并从现在开始使用数组元素更好。了解eval 选项很重要,但在没有必要时不要使用它。
  • 这种方式可以解决问题,但不推荐。如果可能,应该避免使用eval,并且if,代码中不应该有裸评估。我宁愿建议将结构连接起来,即使它会花费一些额外的时间和内存(临时内存开销)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多