5881
|
1 ## Copyright (C) 2006 Paul Kienzle |
|
2 ## |
|
3 ## This file is part of Octave. |
|
4 ## |
|
5 ## Octave is free software; you can redistribute it and/or modify it |
|
6 ## under the terms of the GNU General Public License as published by |
|
7 ## the Free Software Foundation; either version 2, or (at your option) |
|
8 ## any later version. |
|
9 ## |
|
10 ## Octave is distributed in the hope that it will be useful, but |
|
11 ## WITHOUT ANY WARRANTY; without even the implied warranty of |
|
12 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
13 ## General Public License for more details. |
|
14 ## |
|
15 ## You should have received a copy of the GNU General Public License |
|
16 ## along with Octave; see the file COPYING. If not, write to the Free |
|
17 ## Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
|
18 ## 02110-1301, USA. |
|
19 |
|
20 ## -*- texinfo -*- |
6713
|
21 ## @deftypefn {Function File} {[@var{t}, @var{p}] =} orderfields (@var{s1}, @var{s2}) |
5881
|
22 ## Return a struct with fields arranged alphabetically or as specified |
|
23 ## by @var{s2} and a corresponding permutation vector. |
|
24 ## |
|
25 ## Given one struct, arrange field names in @var{s1} alphabetically. |
|
26 ## |
|
27 ## Given two structs, arrange field names in @var{s1} as they appear |
|
28 ## in @var{s2}. The second argument may also specify the order in |
|
29 ## a permutation vector or a cell array of strings. |
|
30 ## |
|
31 ## @seealso{getfield, rmfield, isfield, isstruct, fieldnames, struct} |
|
32 ## @end deftypefn |
|
33 |
|
34 ## Author: Paul Kienzle <pkienzle@users.sf.net> |
|
35 ## Adapted-By: jwe |
|
36 |
|
37 function [t, p] = orderfields (s1, s2) |
|
38 |
|
39 if (nargin == 1 || nargin == 2) |
|
40 if (! isstruct (s1)) |
|
41 error ("orderfields: expecting argument to be a struct"); |
|
42 endif |
|
43 else |
|
44 print_usage (); |
|
45 endif |
|
46 |
|
47 if (nargin == 1) |
|
48 ## One structure: return the fields in alphabetical order. |
6862
|
49 if (isstruct (s1)) |
5881
|
50 names = sort (fieldnames (s1)); |
|
51 endif |
|
52 elseif (nargin == 2) |
6862
|
53 if (isstruct (s2)) |
5881
|
54 ## Two structures: return the fields in the order of s2. |
|
55 names = fieldnames (s2); |
|
56 if (! isequal (sort (fieldnames (s1)), sort (names))) |
5887
|
57 error ("orderfields: structures do not have same fields"); |
5881
|
58 endif |
|
59 elseif (iscellstr (s2)) |
|
60 ## A structure and a list of fields: order by the list of fields. |
|
61 t1 = sort (fieldnames (s1)); |
|
62 t2 = sort (s2(:)); |
|
63 if (! isequal (t1, t2)) |
5887
|
64 error ("orderfields: name list does not match structure fields"); |
5881
|
65 endif |
|
66 names = s2; |
|
67 elseif (isvector (s2)) |
|
68 ## A structure and a permutation vector: permute the order of s1. |
|
69 names = fieldnames (s1); |
|
70 t1 = sort (s2); |
|
71 t1 = t1(:)'; |
6862
|
72 t2 = 1:numel (names); |
5881
|
73 if (! isequal (t1, t2)) |
|
74 error ("orderfields: invalid permutation vector"); |
|
75 endif |
6862
|
76 names = names (s2); |
5881
|
77 endif |
|
78 endif |
|
79 |
|
80 ## Find permutation vector which converts the original name order |
|
81 ## into the new name order. Note: could save a couple of sorts |
|
82 ## in some cases, but performance isn't critical. |
|
83 |
|
84 if (nargout == 2) |
|
85 [oldel, oldidx] = sort (fieldnames (s1)); |
|
86 [newel, newidx] = sort (names); |
|
87 p = oldidx(newidx); |
|
88 endif |
|
89 |
|
90 ## Permute the names in the structure. |
6862
|
91 if (numel (s1) == 0) |
|
92 args = cell (1, 2 * numel (names)); |
|
93 args(1:2:end) = names; |
|
94 args{2:2:end} = {}; |
|
95 t = struct (args{:}); |
|
96 else |
|
97 for i = 1:numel (names) |
|
98 el = names(i); |
|
99 t(:).(el) = s1(:).(el); |
|
100 endfor |
|
101 endif |
5881
|
102 |
|
103 endfunction |