1

For example

test = struct('one', [1;2;3], 'two', [4;5;6]);

I would like to vertically concatenate the vectors in the struct test. For example, if it were defined as a cell array instead test = {[1;2;3], [4;5;6]}, I could do vertcat(test{:}). However, vertcat(test{:}) returns a struct object if test is a struct.

I would like to have a solution that does not involve creating a temporary cell array using struct2cell.

Suever
  • 64,497
  • 14
  • 82
  • 101
Alex
  • 15,186
  • 15
  • 73
  • 127

2 Answers2

5

What you want to do is to actually use struct2array and then flatten the result.

A = reshape(struct2array(test), [], 1);

%   1
%   2
%   3
%   4
%   5
%   6

Benchmark

As a follow-up, I have performed a little bit of a benchmark comparing the usage of struct2cell to struct2array. We would expect the cell2mat(struct2cell()) method to be slower because 1) it is operating on cell arrays and 2) it uses cell arrays rather than numerical arrays which are notoriously slow. Here is the script I used to perform the tests.

function tests()
    sizes = round(linspace(100, 100000));

    times1 = zeros(size(sizes));
    times2 = zeros(size(sizes));

    for k = 1:numel(sizes)
        sz = sizes(k);
        S = struct('one', rand(sz, 1), 'two', rand(sz, 1));
        times1(k) = timeit(@()cellbased(S));
        times2(k) = timeit(@()arraybased(S));
    end

    figure;
    plot(sizes, cat(1, times1 * 1000, times2 * 1000));
    legend('struct2cell', 'struct2array')
    xlabel('Number of elements in S.a and S.b')
    ylabel('Execution time (ms)')
end

function C = cellbased(S)
    C = cell2mat(struct2cell(S));
end

function C = arraybased(S)
    C = reshape(struct2array(S), [], 1);
end

And the results (R2015b)

enter image description here

Suever
  • 64,497
  • 14
  • 82
  • 101
0

In my case I managed to do it using:

cell2mat(struct2cell(test))
Alex
  • 15,186
  • 15
  • 73
  • 127
  • 3
    Why do you have a self-answer where you use `struct2cell` despite explicitly stating in your question that you *don't* want to use `struct2cell`? Also you do realize that this still creates a temporary cell array, right? – Suever Jun 01 '16 at 12:47
  • Sorry, to be precise I did not want to assign a temporary variable explicitly with `tmp = struct2cell`. I did not realise it creates a temporary cell array. It was just the solution I found so it was worth posting in case no one had a better answer. – Alex Jun 01 '16 at 23:36
  • You can think of it kind of like `mean(rand(1e10,1))`. This is still going to consume all of the memory required to hold the random array even though the end result is a single number. I have added a benchmark to my answer to show the performance difference between these two solutions. – Suever Jun 02 '16 at 00:37