3

Is it possible to flatten an array of arbitrarily nested arrays of integers into a flat array of integers in Matlab? For example,

[[1,2,[3]],4] -> [1,2,3,4]

Any kind of guidance will be helpful. Thanks. For example,

a.c = [5,4];
a.b.a=[9];
a.b.d=[1,2];

a= b: [1x1 struct]
   c: [5 4]

In this case, my output will be

output= [9,1,2,5,4]
Mykola
  • 3,343
  • 6
  • 23
  • 39
Chris33
  • 103
  • 2
  • 8
  • Your example array is not MATLAB syntax (or if it is, then both sides are identical so `isequal([[1,2,[3]],4],[1,2,3,4]))` would return `true`) so it's difficult to answer this properly. Can you provide a proper MATLAB example? You can probably do this using `reshape` or `(:)` but the correct answer will depend on your data-type – Dan Jan 11 '16 at 14:10
  • I have edited it. Hopefully its clear now. – Chris33 Jan 11 '16 at 14:15
  • 1
    That is a very different question. How should the algorithm decide on order between `.c` and `.b` and then again between `.a` and `.d`? – Dan Jan 11 '16 at 14:17

2 Answers2

3

I think you will have to adapt the flatten function from the file exchange to use struct2cell so something like this:

function C = flatten_struct(A)

    A = struct2cell(A);
    C = [];
    for i=1:numel(A)  
        if(isstruct(A{i}))
            C = [C,flatten_struct(A{i})];
        else
            C = [C,A{i}]; 
        end
    end

end

This results in:

a.c = [5,4];
a.b.a=[9];
a.b.d=[1,2];

flatten_struct(a)

ans =

    5    4    9    1    2

So the order is in the order you declared your struct instead of in your example order which I presume is alphabetical. But you have control over this so it shouldn't be a problem.

nekomatic
  • 5,988
  • 1
  • 20
  • 27
Dan
  • 45,079
  • 17
  • 88
  • 157
-1

I have a preliminary hack which does work but rather clumsily. It descends recursively, saving structure names and unpacking the returned structure at each "level" .

%  struct2sims converter
function simout = struct2sims(structin)
fnam = fieldnames(structin);
for jf = 1:numel(fnam)
    subnam = [inputname(1),'_',fnam{jf}];
    if isstruct(structin.(fnam{jf}) ) ,
    % need to dive;  build a new variable that's not a substruct
     eval(sprintf('%s = structin.(fnam{jf});', fnam{jf}));
    eval(sprintf('simtmp = struct2sims(%s);',fnam{jf}) );
    % try removing the struct before getting any farther...
    simout.(subnam) = simtmp;
    else
    % at bottom, ok
    simout.(subnam) = structin.(fnam{jf});
    end

end
 %  need to unpack structs here, after each level of recursion
 % returns...
    subfnam = fieldnames(simout);
    for kf = 1:numel(subfnam)
         if isstruct(simout.(subfnam{kf}) ),  
             subsubnam = fieldnames(simout.(subfnam{kf}));
             for fk = 1:numel(subsubnam)
                 simout.([inputname(1),'_',subsubnam{fk}])...
                     = simout.(subfnam{kf}).(subsubnam{fk}) ;
             end
             simout = rmfield(simout,subfnam{kf});
         end
    end
 % if desired write to file with:
 % save('flattened','-struct','simout');
end
Carl Witthoft
  • 20,573
  • 9
  • 43
  • 73