在循环中创建结构的最佳方法是啥?
Posted
技术标签:
【中文标题】在循环中创建结构的最佳方法是啥?【英文标题】:how is the best way to create a struct in a loop?在循环中创建结构的最佳方法是什么? 【发布时间】:2020-09-22 00:28:08 【问题描述】:我想在循环中创建一个结构。这是最初的命令行:
for i = 1:n
if condition
myStruct(i).a = i:
myStruct(i).b = 1:
else
myStruct(i) = myFunction(i):
end
end
myFunction 如下:(真正的有更多字段)
function myStruct = myFunction(i)
myStruct.a = i;
myStruct.b = 0;
end
当第一个循环 (i=1) 的条件为真时,它可以正常工作,否则第一个分配会出错,如下所示:
subscripted assignment between dissimilar structures.
为了应对它,我按照以下方式进行操作,但我正在寻找更好更有效的解决方案。
for i = 1:n
if condition
myStruct(i).a = i:
myStruct(i).b = 1:
else
if i == 1
myStruct = myFunction(i);
else
myStruct(i) = myFunction(i):
end
end
end
但我更喜欢一些较短的解决方案。我很感激任何建议。
【问题讨论】:
你似乎只需要for k=1:n, myStruct(k) = myFunction(k); end
@SardarUsama 我如何得到错误并尝试使用 if 块修复它。
如果你先做temp = myFunction(i);
然后myStruct(i)=temp
会有效吗?
@hyiltiz 不。我试过了,同样的错误。当 myStruct 仍然为空时,无论如何都无法建立索引。
【参考方案1】:
使用 arrayfun 更有效。如果 myFunction 总是返回具有相同成员的结构,请尝试:
myStruct = arrayfun(@myFunction, 1:n);
编辑澄清:
在每次迭代中添加时,每次迭代都会更改数组的维度。这效率不高。 Arrayfun 允许 Matlab 为您预分配结构数组并管理值分配。
编辑到地址编辑过的 OP
更新功能:
function myStruct = myFunction(i, condition)
myStruct.a = i;
if condition
myStruct.b = 1;
else
myStruct.b = 0;
end
end
更新调用:
s = arrayfun(@(x) myFunction(x, condition), 1:n);
【讨论】:
我不确定这是否更有效(数组 fun 只是一个 for 循环),但绝对更优雅。 尝试使用非常大的 n 值。 对,但这并没有使这更快,OP 可以预先分配他的数组,他们只是没有。它不是因为它的arrayfun
而更快,它更快是因为它预分配,这与循环与arrayfun 速度无关。
很公平。 OP 中的代码不会预先分配。 OP 正在寻找更短的解决方案,arrayfun 提供了这一点。我刚刚在 2 种方法之间进行了 10k 次迭代的快速测试。 Arrayfun 耗时 0.2083 秒,OP 方法耗时 1.4782。
@prs 为什么不在 myFunction 的输入参数中包含条件并让它处理赋值?【参考方案2】:
正如其他人已在此处评论的那样:预先分配,忘记 i==1
案例。
myStruct(n) = myFunction(n); % or any other way of creating an instance of your structure, not important.
for i = 1:n
if condition
myStruct(i).a = i:
myStruct(i).b = 1:
else
myStruct(i) = myFunction(i):
end
end
【讨论】:
以上是关于在循环中创建结构的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章
开放式加速器 | Fortran 90:并行化嵌套 DO 循环的最佳方法是啥?
在 ASP.NET MVC 中构造视图层次结构的最佳方法是啥?