1 ## Copyright (C) 2007-2012 David Bateman
2 ## Copyright (C) 2010 VZLU Prague
4 ## This file is part of Octave.
6 ## Octave is free software; you can redistribute it and/or modify it
7 ## under the terms of the GNU General Public License as published by
8 ## the Free Software Foundation; either version 3 of the License, or (at
9 ## your option) any later version.
11 ## Octave is distributed in the hope that it will be useful, but
12 ## WITHOUT ANY WARRANTY; without even the implied warranty of
13 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 ## General Public License for more details.
16 ## You should have received a copy of the GNU General Public License
17 ## along with Octave; see the file COPYING. If not, see
18 ## <http://www.gnu.org/licenses/>.
21 ## @deftypefn {Function File} {} structfun (@var{func}, @var{S})
22 ## @deftypefnx {Function File} {[@var{A}, @dots{}] =} structfun (@dots{})
23 ## @deftypefnx {Function File} {} structfun (@dots{}, "ErrorHandler", @var{errfunc})
24 ## @deftypefnx {Function File} {} structfun (@dots{}, "UniformOutput", @var{val})
26 ## Evaluate the function named @var{name} on the fields of the structure
27 ## @var{S}. The fields of @var{S} are passed to the function @var{func}
30 ## @code{structfun} accepts an arbitrary function @var{func} in the form of
31 ## an inline function, function handle, or the name of a function (in a
32 ## character string). In the case of a character string argument, the
33 ## function must accept a single argument named @var{x}, and it must return
34 ## a string value. If the function returns more than one argument, they are
35 ## returned as separate output variables.
37 ## If the parameter "UniformOutput" is set to true (the default), then the
39 ## must return a single element which will be concatenated into the
40 ## return value. If "UniformOutput" is false, the outputs are placed into a
42 ## with the same fieldnames as the input structure.
46 ## s.name1 = "John Smith";
47 ## s.name2 = "Jill Jones";
48 ## structfun (@@(x) regexp (x, '(\w+)$', "matches")@{1@}, s,
49 ## "UniformOutput", false)
58 ## Given the parameter "ErrorHandler", @var{errfunc} defines a function to
59 ## call in case @var{func} generates an error. The form of the function is
62 ## function [@dots{}] = errfunc (@var{se}, @dots{})
66 ## where there is an additional input argument to @var{errfunc} relative to
67 ## @var{func}, given by @var{se}. This is a structure with the elements
68 ## "identifier", "message" and "index", giving respectively the error
69 ## identifier, the error message, and the index into the input arguments
70 ## of the element that caused the error. For an example on how to use
71 ## an error handler, @pxref{doc-cellfun, @code{cellfun}}.
73 ## @seealso{cellfun, arrayfun, spfun}
76 function varargout = structfun (func, S, varargin);
82 nargs = length (varargin);
84 recognized_opts = {"UniformOutput", "ErrorHandler"};
85 uo_str = recognized_opts{1};
87 uniform_output = true;
90 opt_match = strcmpi (varargin{nargs-1}, recognized_opts);
92 uniform_output = varargin{nargs};
102 error ("structfun: invalid options");
105 varargout = cell (max ([nargout, 1]), 1);
106 [varargout{:}] = cellfun (func, struct2cell (S), varargin{:});
108 if (! uniform_output)
109 varargout = cellfun ("cell2struct", varargout, {fieldnames(S)}, {1}, uo_str, false);
115 %! s.name1 = "John Smith";
116 %! s.name2 = "Jill Jones";
117 %! l.name1 = "Smith";
118 %! l.name2 = "Jones";
119 %! o = structfun (@(x) regexp (x, '(\w+)$', "matches"){1}, s,
120 %! "UniformOutput", false);
123 %!function [a, b] = __twoouts (x)
129 %! s = struct ("a", {1, 2, 3}, "b", {4, 5, 6});
130 %! c(1:2, 1, 1) = [2; 8];
131 %! c(1:2, 1, 2) = [4; 10];
132 %! c(1:2, 1, 3) = [6; 12];
133 %! d(1:2, 1, 1) = [1; 16];
134 %! d(1:2, 1, 2) = [4; 25];
135 %! d(1:2, 1, 3) = [9; 36];
136 %! [aa, bb] = structfun(@__twoouts, s);
141 %! s = struct ("a", {1, 2, 3}, "b", {4, 5, 6});
142 %! c = struct ("a", {2, 4, 6}, "b", {8, 10, 12});
143 %! d = struct ("a", {1, 4, 9}, "b", {16, 25, 36});
144 %! [aa, bb] = structfun(@__twoouts, s, "UniformOutput", false);