Formatted printing of contents of structures and fields in matlab / octave

I need to print in the command window the contents of the structure with the appropriate field names and some text around each structure element.

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

In the afternoon of my headache, I ended up with an expression (which doesn't work) and a loop (which does).

The question is - 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 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

      

A simple expression printf

, however, returns this strange 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

      

Recommendations appreciated

+3


source to share


3 answers


Just adding 2 ยข to the above answers.

"No loop" is not necessarily always faster. Especially now with the Matlab JL compiler for loops. So don't just avoid the loops and end up in an ugly code golf club for just one liner. Not to mention, one-liners are not necessarily equal to vectorization. If you are in doubt about speed, do a simple benchmark test.

Plus, loops tend to be much more readable, so unless you get massive speed-up by avoiding it, it's generally not necessary to sacrifice readability for micro-optimization.

Having said that, here's how I would write this 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 are using octave, octave specifically provides the following beautiful syntax:



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

      

Some tests on my machine (octave, no JIT compilation, time elapsed after 10,000 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 approaches for the loop is actually faster than the one-line approach.


Also note that box

- this is the name of the function in matlab / octave; it's generally a bad idea to use variable names that are shadow built-in functions. You can usually get around this by using capital letters for variables, or just look for a function with that name before calling a variable that

+2


source


In GNU Octave (see section "Answers to the Wave" for 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))'{:});

      



and "105.000" appears because you are feeding hardware as% f. Check this out (which should explain your strange result):

printf ('%f', 'iron')

      

+4


source


This method should work for both MATLAB and Octave:

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

      


In MATLAB, you must enclose a statement with parentheses ()

where they are used. Therefore you cannot do

c = struct2cell(box){:};

      

and instead need to do

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

      

MATLAB also requires you to use fprintf

, not printf

. You can see some language differences here .


+2


source







All Articles