In my code, I have a structure and in a field of it, I want to sort its values.
For instance, in the field of File_Neg.name
there are the following values, and They should be sorted as the right values.
File_Neg.name --> Sorted File_Neg.name
'-10.000000.dcm' '-10.000000.dcm'
'-102.500000.dcm' '-12.500000.dcm'
'-100.000000.dcm' '-100.000000.dcm'
'-107.500000.dcm' '-102.500000.dcm'
'-112.500000.dcm' '-107.500000.dcm'
'-110.000000.dcm '-110.000000.dcm'
'-12.500000.dcm' '-112.500000.dcm'
There is a folder that there are some pictures with negative labels in it (above example are labels of pictures). I want to get them in the same order as present in the folder(that's mean the Sorted File_Neg.name
). But when running the following code the values of Files_Neg.name
load as the above example (left: File_Neg.name
), while I want the right form.
I have also seen this and that but they didn't help me.
How to sort values of a field in a structure in Matlab?
Files_Neg = dir('D:\Rename-RealN');
File_Neg = dir(strcat('D:\Rename-RealN\', Files_Neg.name, '\', '*.dcm'));
% when running the code the values of Files_Neg.name load as the above example (left: File_Neg.name)
File_Neg.name
:
This answer to one of the questions linked in the OP is nearly correct for the problem in the OP. There are two issues:
The first issue is that the answer assumes a scalar value is contained in the field to be sorted, whereas in the OP the values are char arrays (i.e. old-fashioned strings).
This issue can be fixed by adding 'UniformOutput',false
to the arrayfun
call:
File_Neg = struct('name',{'-10.000000.dcm','-102.500000.dcm','-100.000000.dcm','-107.500000.dcm','-112.500000.dcm','-110.000000.dcm','-12.500000.dcm'},...
'folder',{'a','b','c','d','e1','e2','e3'});
[~,I] = sort(arrayfun(@(x)x.name,File_Neg,'UniformOutput',false));
File_Neg = File_Neg(I);
File_Neg
is now sorted according to dictionary sort (using ASCII letter ordering, meaning that uppercase letters come first, and 110 still comes before 12).
The second issue is that OP wants to sort according to the magnitude of the number in the file name, not using dictionary sort. This can be fixed by extracting the value in the anonymous function applied using arrayfun
. We use str2double
on the file name, minus the last 4 characters '.dcm'
:
[~,I] = sort(arrayfun(@(x)abs(str2double(x.name(1:end-4))),File_Neg));
File_Neg = File_Neg(I);
Funnily enough, we don't want to use 'UniformOutput',false
any more, since the anonymous function now returns a scalar value.