I need to print to command window the contents of a structure with corresponding field names and some text around every structure element.
i.e. This something [fieldname(i)] has the value of [struct.fieldname(i) value] something.
After half a day of headache I ended up with an expression (which does not work) and a loop (which works).
Question - is there a way to do this without a loop?
Code:
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){:})
The loop returns a sensible output exactly as I want:
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
Just the printf
expression however returns this weird output:
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
Advice appreciated
Just adding my 2¢ to the above answers.
"Without a loop" is not necessarily always faster. Especially now with matlab's JIT-compiler for loops. So don't just avoid loops and end up with ugly-looking code-golf just for the sake of having a one-liner. Not to mention, one-liners do not necessarily equal vectorisation. If in doubt about speed, do a simple test-case benchmark.
Furthermore loops are generally much more readable, so unless you get a massive speedup from avoiding it, it's generally not necessarily worth sacrificing readability for the sake of micro-optimisations.
Having said that, here's how I would have written that loop:
for CellStr = fieldnames(box).'
Name = CellStr{1};
fprintf('There are %.3f kg of %s in the box\n', box.(Name), Name)
end
Or, if you're using octave, octave specifically provides the following lovely syntax:
for [Val, Field] = box
fprintf('There are %.3f kg of %s in the box\n', Val, Field)
end
Some benchmarks on my machine (octave, no JIT compilation, time elapsed after 10000 iterations):
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
So, see, in this particular case, one of the for-loop approaches is in fact faster than the one-liner approach.
Also note that box
is the name of a function in matlab / octave; it's generally a bad idea to use variable names that shadow builtin functions. You can generally get around that by using Capital letters for variables, or simply look for a function by that name before calling your variable that