image thumbnail
from struct2table by Karl
displays a struct's contents in a clear way...

struct2table.m
%STRUCT2TABLE Display struct content in table format
%   STRUCT2TABLE(S) displays a table with the field names in the headline
%   and one row for each struct element:
%
%   #        [field name 1]         [field name 2] ...
%   
%   1 S(1).([field name 1])  S(1).([field name 2]) ...
%   2 S(2).([field name 1])  S(2).([field name 2]) ...
%
%   STRUCT2TABLE(S, F) displays only the fields with the names that are
%   contained in the cell-array F.
%
%      If the elements of F itself are also two-element cell arrays (e.g.
%      F{1} = {'field1', 'round'}) individual display modes for each
%      field's values can be set. Until now, two modes have been
%      implemented, both only effective with numbers:
%
%      'normal' - simply the value of the scalar
%      'round'  - the values are rounded before being displayed
%
%      (also see "user parameters" below.)
%
%   STRUCT2TABLE(H, S, F) displays a headline string H before creating the
%   table.
%
%   USER PARAMETERS Some aspects of the layout of the table can be set
%   globally. In detail, the parameters are:
%
%      N_decimal_digits - used to globally set the number of decimal digits
%                         displayed
%                         (applies only to numbers)
%      str_disp_true    - the string used to indicate locigal true
%                         (applies only to logicals)
%      str_disp_false   - the string used to indicate logical false
%                         (applies only to logicals)

%   For complaints, advice or comments in general contact me via
%   faktor.digital.audio@gmail.com
function struct2table(varargin)

% user parameters__________________________________________________________
N_decimal_digits = 2;
str_disp_true = 'yes';
str_disp_false = 'no';
default_parameter = 'round';
% _________________________________________________________________________

% handle the input arguments:
if nargin == 1
    stIn = varargin{1};
elseif nargin == 2
    stIn = varargin{1};
    fieldNames = varargin{2};
elseif nargin == 3
    s_tablename = varargin{1};
    stIn = varargin{2};
    fieldNames = varargin{3};
end

% for use with the MATLAB Compiler:
% (had problems with the "high line" char on the windows console)
if ~isdeployed()
    char_line = '';
else
    char_line = '-';
end

if nargin == 3
    % handle the headline...
    L_s_tablename = length(s_tablename);
    fprintf([s_tablename '\n']);
    fprintf([repmat(char_line, 1, L_s_tablename) '\n']);
end

% the number of struct elements
nEntrys = length(stIn);

if (nargin == 1)
    % display all fields...
    fieldNames = fieldnames(stIn);
end
nFields = length(fieldNames);

% determine the column widths by scanning all struct entries...
fprintfArgs = ['''' '#' '''' ','];
formatString = ['%3s'];
for i = 1 : nFields
    cur_fieldName = fieldNames{i};
    if iscell(cur_fieldName)
        % obviously a special field display parameter has been set...
        temp_cell = cur_fieldName;
        cur_fieldName = temp_cell{1};
        cur_parameter = temp_cell{2};
    else
        cur_parameter = default_parameter;
    end
    lengthFieldName = max(getLongestEntry(stIn, cur_fieldName, cur_parameter), length(cur_fieldName));
    formatString = [formatString '   %' num2str(lengthFieldName) 's']; %#ok<AGROW>
    fprintfArgs = [fprintfArgs '''' cur_fieldName '''']; %#ok<AGROW>
    if (i < nFields)
        fprintfArgs = [fprintfArgs ',']; %#ok<AGROW>
    end
end

formatString = [formatString '\n'];

len = eval(['fprintf(' '''' formatString '''' ',' fprintfArgs ');']);
underLine = repmat(char_line, 1, len);
fprintf([underLine '\n']);

% actually print the table:
for i = 1 : nEntrys
    fprintfArgs = ['''' num2str(i) '''' ',' ];
    for j = 1 : nFields
        temp_cell = fieldNames{j};
        if iscell(temp_cell)
            cur_fieldName = temp_cell{1};
            cur_parameter = temp_cell{2};
        else
            cur_fieldName = temp_cell;
            cur_parameter = default_parameter;
        end
        if ischar(stIn(i).(cur_fieldName))
            cur_additional_arg = stIn(i).(cur_fieldName);
        elseif isnumeric(stIn(i).(cur_fieldName))
            switch cur_parameter
                case 'normal'
                    cur_additional_arg = mat2str(stIn(i).(cur_fieldName));
                case 'round'
                    cur_additional_arg = mat2str(round(stIn(i).(cur_fieldName)*10^(N_decimal_digits)) / 10^(N_decimal_digits));
                %case 'sec2time'
                %    cur_additional_arg = sec2time(stIn(i).(cur_fieldName));
            end
        elseif islogical(stIn(i).(cur_fieldName))
            if stIn(i).(cur_fieldName)
                cur_additional_arg = str_disp_true;
            else
                cur_additional_arg = str_disp_false;
            end
        elseif iscell(stIn(i).(cur_fieldName))
            cur_additional_arg = cell2mat(stIn(i).(cur_fieldName));
        end
        fprintfArgs = [fprintfArgs '''' strrep(cur_additional_arg, '''', '''''') '''']; %#ok<AGROW>
        if (j < nFields)
            fprintfArgs = [fprintfArgs ',']; %#ok<AGROW>
        end
    end
    eval(['fprintf(' '''' formatString '''' ',' fprintfArgs ');']);
end

% _________________________________________________________________________
% function to obtain the length of the longest value of a certain field
    function maxLength = getLongestEntry(stIn, fieldName, disp_parameter)
        
        % the number of elements in the struct
        nEntrys = length(stIn);
        lengthOfThisField = 0;
        
        % this loop generates all strings that will show up in the final table
        % later but only uses them to determine their length:
        for sf_counter = 1 : nEntrys
            if (isstruct(stIn(sf_counter).(fieldName)))
                continue;
            end
            if ischar(stIn(sf_counter).(fieldName))
                curLength = length(stIn(sf_counter).(fieldName));
            elseif isnumeric(stIn(sf_counter).(fieldName))
                switch disp_parameter
                    case 'normal'
                        curLength = length(mat2str(stIn(sf_counter).(fieldName)));
                    case 'round'
                        curLength = length(mat2str(round(stIn(sf_counter).(fieldName)*10^(N_decimal_digits)) / 10^(N_decimal_digits)));
                        %case 'sec2time'
                        %    % special display of times...
                        %    curLength = length(sec2time(stIn(sf_counter).(fieldName)));
                end
            elseif islogical(stIn(sf_counter).(fieldName))
                if stIn(sf_counter).(fieldName)
                    curLength = length(str_disp_true);
                else
                    curLength = length(str_disp_false);
                end
            elseif iscell(stIn(sf_counter).(fieldName))
                curLength = length(cell2mat(stIn(sf_counter).(fieldName)));
            else
                warning('this field value type is not yet supported');
            end
            if curLength > lengthOfThisField
                lengthOfThisField = curLength;
            end
        end
        maxLength = lengthOfThisField;
    end % of function "maxLength()"
end % of function "struct2table()"

Contact us