matlab/octave 中结构内容和字段名的格式化打印

formatted print of structures contents and fieldnames in matlab/octave

我需要打印命令 window 结构的内容以及相应的字段名称和每个结构元素周围的一些文本。

This something [fieldname(i)] has the value of [struct.fieldname(i) value] something.

经过半天的头痛,我最终得到了一个表达式(不起作用)和一个循环(起作用)。

问题 - 有没有办法不用循环就可以做到这一点?

代码:

box.apples = 25
box.cherries = 0.5
box.iron = 0.085

% Loop method (works)
for i = (1:length(struct2cell(box))) ;
    printf('There are %.3f kg of %s in the box \n', struct2cell(box){i}, fieldnames(box){i})
end
% Single expression method (doesn't work)
printf('There are %.3f kg of %s in the box \n', struct2cell(box){:}, fieldnames(box){:})

循环 returns 一个合理的输出,完全符合我的要求:

There are 25.000 kg of apples in the box 
There are 0.500 kg of cherries in the box
There are 0.085 kg of iron in the box

只是 printf 表达式,但是 returns 这个奇怪的输出:

There are 25.000 kg of  in the box
There are 0.085 kg of apples in the box
There are 99.000 kg of herries in the box
There are 105.000 kg of ron in the box

感谢建议

在 GNU Octave 中(参见 Wolfies 对 Matlab 的回答):

box.apples = 25
box.cherries = 0.5
box.iron = 0.085
printf('There are %.3f kg of %s in the box \n',
       horzcat(struct2cell(box),fieldnames(box))'{:});

并且出现“105.000”是因为您将 'iron' 作为 %f 喂食。检查一下(这应该可以解释您的奇怪结果):

printf ('%f', 'iron')

此方法应该适用于 MATLAB 和 Octave:

c = vertcat(struct2cell(box).',fieldnames(box).');
fprintf('There are %.3f kg of %s in the box \n', c{:});

在 MATLAB 中,您必须 end 语句在使用圆括号 () 的地方。所以你不能做

c = struct2cell(box){:};

并且必须改为

c = struct2cell(box);
c = c{:};

MATLAB 还要求您使用 fprintf,而不是 printf。您可以看到一些语言差异 here.


只需将我的 2¢ 添加到以上答案即可。

"Without a loop" 不一定总是 更快。特别是现在使用 matlab 的 JIT 循环编译器。因此,不要只是为了拥有一个单行代码而避免循环并以丑陋的代码高尔夫结束。更不用说,一行 不一定等于向量化 。如果对速度有疑问,请做一个简单的测试用例基准测试。

此外,循环通常更具可读性,因此除非您通过避免它获得巨大的加速,否则通常不一定值得为了微优化而牺牲可读性。

话虽如此,这就是我编写该循环的方式:

  for CellStr = fieldnames(box).'
    Name = CellStr{1};
    fprintf('There are %.3f kg of %s in the box\n', box.(Name), Name)
  end

或者,如果您使用的是 Octave,Octave 特别提供了以下可爱的语法:

for [Val, Field] = box
  fprintf('There are %.3f kg of %s in the box\n', Val, Field)
end

我机器上的一些基准测试(八度、无 JIT 编译、10000 次迭代后经过的时间):

one-liner in answers above = 0.61343 seconds
top loop shown above       = 0.92640 seconds
bottom loop shown above    = 0.41643 seconds <-- wins
loop shown in the question = 1.6744  seconds

所以,请看,在这种特殊情况下,其中一种 for 循环方法实际上 比单行方法 更快。


还要注意box是matlab/octave中的一个函数名;使用隐藏内置函数的变量名通常不是一个好主意。您通常可以通过对变量使用大写字母来解决这个问题,或者在调用您的变量之前简单地查找具有该名称的函数 that