使用包含单元格长度的向量将嵌套结构转换为单元格数组

时间:2017-09-18 12:37:15

标签: matlab for-loop cell

我有以下格式的嵌套结构a

Sizes = [10, 9, 8, 11, 10];
cells = 5;
for i = 1:cells
    for j = 1:40
        a(i).b(j) = rand(1,1);
    end
    a(i).Size = Sizes(i);
end

是否可以将1:a(i).Size的{​​{1}}值放入单元格数组而不使用for循环而不使用b

结果应如下所示:

cellfun

2 个答案:

答案 0 :(得分:3)

所以我试着改进你的代码,你可以看到下面的结果:

%% My approach to solve the question (it has a slightly better runtime)
function c = myapproach(a, cells)
c = {a.b};
sz = [a.Size];
for i = 1:cells
    c{i} = c{i}(1:sz(i));
end
end

虽然这不会避免for循环,但它的运行时稍微好一点。我得到的运行时间(单元格= 50000)是:@yourapproach = 0.0889, @myapproach = 0.0721, @rahnema1 = 0.2329

以下是我用来解决这个问题的代码。我还对用于生成a的代码进行了一些改进(由评论标记)

function solveit()
cells = 50000;
maxVal = 40;
Sizes = randi(maxVal, 1, cells);
a(cells) = struct('Size', 0, 'b', []); %% Improved by preallocating a
for i = 1:cells
    a(i).b = rand(1, maxVal); %% Improved by removing the unnecessary double loop
    a(i).Size = Sizes(i);
end
fun1 = @() yourapproach(a, cells);
fun2 = @() myapproach(a, cells);
fun3 = @() rahnema1(a);
%% Show runtimes
timeit(fun1)
timeit(fun2)
timeit(fun3)
c1 = fun1();
c2 = fun2();
c3 = fun3();
%%Show approach equivalence
disp(isequal(c1, c2))
disp(isequal(c1, c3))
end
%% Your approach
function c = yourapproach(a, cells)
c = cell(1, cells);
for i = 1:cells
    sz = a(i).Size;
    c{1,i} = a(i).b(1:sz);
end
end
%% Approach mentioned by rahnema1
function c = rahnema1(a)
cc = struct2cell(a);
sz = [cc{1:2:end}];
sz = [sz;40-sz];
dat = [cc{2:2:end}];
c = mat2cell(dat, 1, sz(:));
c = c(1:2:end);
end

编辑:我正在添加arrayfun方法,但它至少比for循环慢10倍

function c = newapproach(a)
sz = [a.Size];
c = arrayfun(@(x, y) x.b(1:y), a, sz, 'UniformOutput', false);
end

答案 1 :(得分:1)

这是一个没有循环的解决方案。你可以将它与你的方法进行比较,看看女巫更有效:

cc=struct2cell(a)
sz = [cc{2:2:end}];
sz = [sz;40-sz]
dat = [cc{1:2:end}];
result = mat2cell(dat,1,sz);
result = result(1:2:end);