使用struct作为向量的索引

时间:2017-06-14 12:34:48

标签: octave

是否有一个“更好”(意味着可读和矢量化)的方法来使用带索引的结构来生成结果结构?

# struct values are indices into b
a.foo = 2;
a.bar = 3;

b = [e pi 123 1337];

## the loopy way
for [val, key] = a
  c.(key) = b(val);
endfor

disp (c)

给出了期望的结果

scalar structure containing the fields:

  foo =  3.1416
  bar =  123

或其他笨拙且几乎混淆的方式:

d = cell2struct(num2cell(b([struct2cell(a){:}])'), fieldnames(a));
assert (c, d);

1 个答案:

答案 0 :(得分:3)

理论上,你正在寻找的可爱的单行可能是:

structfun (@ (x) b(x), a, 'UniformOutput', false);

然而,structfun,就像其他“有趣”的亲戚一样,似乎只是语法糖而不是实际的矢量化。事实上,最快(也可以说是最干净)的方法似乎确实是你的循环:

基准:

octave:1>  a.foo = 2; a.bar = 3; b = [e pi 123 1337];

octave:2>  # loop method #
        >  tic; for i = 1 : 100; 
        >    for [val, key] = a; S1.(key) = b(val); end; 
        >  end; toc
Elapsed time is 0.00160003 seconds.

octave:3>  # cell2struct method # 
        >  tic; for i = 1 : 100; 
        >    S2 = cell2struct(num2cell(b([struct2cell(a){:}])'), fieldnames(a));
        >  end; toc
Elapsed time is 0.006423 seconds.

octave:4>  # structfun method #
        >  tic; for i = 1: 100
        >    S3 = structfun(@ (x) b(x), a, 'UniformOutput', false);
        >  end; toc
Elapsed time is 0.279853 seconds.

<子> PS。但请注意,如果你有一个数组结构,那么for循环方法将工作“按原样”,而structfun方法将