For example, I have a structure:
data = struct('CL', [0.51 0.51 0.52 0.52 0.55 0.55], 'Mach', [0.7 0.8 0.7 0.8 0.7 0.8], 'CG', [.25 .27 .25 .30 .27 .25])
If I wanted to sort first by CG, then Mach, and finally by CL, the result would be:
CG = [.25 .25 .25 .27 .27 .30]
Mach = [0.7 0.7 0.8 0.7 0.8 0.8]
CL = [ .51 .52 .55 .55 .51 .52]
Any ideas? Thank you for your help!
John
To me, "sort a structure" implies sorting the elements of a structure array. What you're asking to do is exactly accomplished by sortrows.
d=[data.CL' data.Mach' data.CG'];
d=sortrows(d,[3 2 1])
data.CG=d(:,3)'; data.Mach=d(:,2)'; data.CL=d(:,1)';
Am I misunderstanding?
For example, if I add data.Names, I would want to sort by CG, then by Names, then by CL.
I see. Doesn't this mean you'll have to manually write comparison functions for every field? The most straightforward solution I can think of is:
-compute some sort of ordered index for each non-scalar field, as well as a "lookup table", probably as a cell array
-populate a 2D array with the values of the scalar fields OR the ordered indices
-call sortrows
-convert back to your original struct format by using the ordered indices to reference the lookup table
I'm not sure if Matlab has anything more direct than this, hopefully someone else has a better suggestion.
one of the (not so many) solutions
% the data
d.a=1:4;
d.b=[-1,-5,-10,-2];
d.c=[4,1,5,3];
d.s={'b','c','a','a'};
% - sort according to field #
csort=[4,3];
% the engine
fn=fieldnames(d);
c=struct2cell(d);
[ia,ix,ix]=cellfun(@unique,c,'uni',false);
cx=cat(1,ix{:}).';
[cs,cxx]=sortrows(cx,csort);
cn=num2cell(cs.',2);
ns=cellfun(@(x,y) x(y),ia,cn,'uni',false);
r=cell2struct(ns,fn);
% the result
disp(d);
disp(r);
%{
% d =
a: [1 2 3 4]
b: [-1 -5 -10 -2]
c: [4 1 5 3]
s: {'b' 'c' 'a' 'a'}
% r =
a: [4 3 1 2]
b: [-2 -10 -1 -5]
c: [3 5 4 1]
s: {'a' 'a' 'b' 'c'}
%}
us
I see that you converted the struct2cell. Are there any other advantages to using structs other than using fieldnames?
How come there aren't struct functions to do this? MS Excel has a very nice sort routine, I would have thought this would be easy to implement in Matlab? Or is it a philosophical issue? Should I not be using Matlab to sort arrays of data? What if I want to do Excel-type things in Matlab?
The problem you described involved sorting the fields of a scalar struct
based on the contents of other fields of that struct. In your case, where
all the fields were the same size and data type, that makes sense. But in
the more general case:
S = struct('CG', (1:10).', 'mach', single(magic(6)), 'CL', 'Live long and
prosper')
what would it mean to sort S "first by CG, then Mach, and finally by CL"?
CG is a 10-by-1 array of doubles, mach is a 6-by-6 array of singles, and CL
is a 1-by-21 array of chars, so no two of the fields contain data of the
same data type or size. [Yes, the example is a bit contrived, but I'm sure
you can think of scenarios where a struct array may contain fields of
different types or sizes.]
If all your data is homogeneous in type and size, you might want to store it
in a regular array rather than a struct array. From your original example:
CL = [0.51 0.51 0.52 0.52 0.55 0.55];
Mach = [0.7 0.8 0.7 0.8 0.7 0.8];
CG = [.25 .27 .25 .30 .27 .25];
data = [CL; Mach; CG];
and then a sort of data just involves SORTROWS directly.
--
Steve Lord
sl...@mathworks.com
comp.soft-sys.matlab (CSSM) FAQ: http://matlabwiki.mathworks.com/MATLAB_FAQ
oleg