将中间级别插入嵌套的struct数组中

时间:2017-06-02 13:47:28

标签: matlab struct vectorization

我想按如下方式重新排序结构:

Server Error in '/' Application.

Runtime Error

Description: An application error occurred on the server. The current custom error settings for this application prevent the details of the application error from being viewed remotely (for security reasons). It could, however, be viewed by browsers running on the local server machine. 

Details: To enable the details of this specific error message to be viewable on remote machines, please create a <customErrors> tag within a "web.config" configuration file located in the root directory of the current web application. This <customErrors> tag should then have its "mode" attribute set to "Off".


<!-- Web.Config Configuration File -->

<configuration>
    <system.web>
        <customErrors mode="Off"/>
    </system.web>
</configuration>

Notes: The current error page you are seeing can be replaced by a custom error page by modifying the "defaultRedirect" attribute of the application's <customErrors> configuration tag to point to a custom error page URL.


<!-- Web.Config Configuration File -->

<configuration>
    <system.web>
        <customErrors mode="RemoteOnly" defaultRedirect="mycustompage.htm"/>
    </system.web>
</configuration>

以下嵌套循环有效:

%// original struct
s(1).a = rand(10,1);
s(2).a = rand(10,1);
s(1).b = rand(10,1);
s(2).b = rand(10,1);

%// reorder to:
y(1).a = s(1).a;
y(2).a = s(2).a;
y(1).b.c = s(1).b;
y(2).b.c = s(2).b;

但这似乎对我来说太过分了。有任何想法如何优化或简化它?

我使用临时值进行了大量实验,使用fieldToMove = 'b'; newFieldname = 'c'; fn = fieldnames(s); for ii = 1:numel(fn) for jj = 1:numel(s) if strcmp(fn{ii},fieldToMove) y(jj).(fn{ii}).(newFieldname) = s(jj).(fn{ii}); else y(jj).(fn{ii}) = s(jj).(fn{ii}); end end end 删除了原始字段,并使用rmfield设置了新字段,但到目前为止还没有任何工作,因为标量结构始终是必需的。我有什么功能可以忽略吗?

3 个答案:

答案 0 :(得分:3)

使用struct + num2cell的组合可以完成此操作

y = struct('a', {s.a}, 'b', num2cell(struct('c', {s.b})));

答案 1 :(得分:2)

通过预先分配y=s,我们可以跳过if-else语句并删除其中一个for循环。如果需要,我们可以添加另一个for循环,以允许fieldToMovenewFieldname成为单元格数组,从而移动多个字段。请注意,如果您只对移动单个字段的情况感兴趣,则可以删除内部for循环。

s(1).a = rand(10,1);
s(2).a = rand(10,1);
s(1).b = rand(10,1);
s(2).b = rand(10,1);
s(1).d = rand(10,1);
s(2).d = rand(10,1);

fieldsToMove = {'b','d'};
newFieldnames = {'c','e'};

y = s;
for ii = 1:numel(y)
    for jj = 1:numel(fieldsToMove)
        y(ii).(fieldsToMove{jj}) = struct(newFieldnames{jj},s(ii).(fieldsToMove{jj}));
    end
end

答案 2 :(得分:2)

一种选择是使用arrayfunsetfield,如下所示:

y = s;
y = arrayfun(@(s) setfield(s, 'b', struct('c', s.b)), y);

另一个选项是distribute修改后的字段b

y = s;
temp = num2cell(struct('c', {y.b}));
[y.b] = temp{:};