Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Insert intermediate level into nested struct array

I'd like to reorder a struct as follows:

%// 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;

The following nested loop works:

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

But it seems a great overkill to me. Any ideas how to optimize or simplify it?


I experimented a lot with temporary values, removing the original field with rmfield and set the new one with setfield, but nothing worked so far as always a scalar structur is required. Is there some function I'm overlooking?

like image 395
Robert Seifert Avatar asked Jun 02 '17 13:06

Robert Seifert


2 Answers

One option is to use arrayfun and setfield like so:

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

Another option is to distribute a modified field b:

y = s;
temp = num2cell(struct('c', {y.b}));
[y.b] = temp{:};
like image 40
gnovice Avatar answered Sep 24 '22 01:09

gnovice


Using a combination of struct + num2cell this can be done

y = struct('a', {s.a}, 'b', num2cell(struct('c', {s.b})));
like image 198
rahnema1 Avatar answered Sep 22 '22 01:09

rahnema1