Sorting a custom enumeration
Afficher commentaires plus anciens
For various reasons, I want to be able to define an enumeration. This enumeration will have some properties. I'd also like to be able to use it as a key.
Undefined function 'sort' for input arguments of type 'MyGreatEnum'.
However, methods like 'unique' don't work, which is strange for me, as there is clearly a well defined set of unique enums in a list of enums, that are from the same class.
Any ideas?
i.e. I'd like to do
events
events =
2×1 MyGreatEnum enumeration array
MyGreatEnum1
MyGreatEnum2
unique(events)
Error using sort
Undefined function 'sort' for input arguments of type 'MyGreatEnum'.
Error in unique>uniqueR2012a (line 211)
sortA = sort(a);
Error in unique (line 103)
[varargout{1:nlhs}] = uniqueR2012a(varargin{:});
Réponse acceptée
Plus de réponses (1)
rmiku
le 15 Juil 2021
I believe I have a better option: overload the built-in sort() function in your enumeration definition.
I built out your enumeration to have a few properties. This is how I ran into your issue.
classdef myGreatEnum
enumeration
% a b c
mGE1 (1, 2, 3)
mGE2 (4, 5, 6)
mGE3 (7, 8, 9)
end
properties
a
b
c
end
methods
function enum = myGreatEnum(varargin)
% Default constructor, sets properties
if(nargin == 3)
% Enumeration definitions are dependent on this order
% don't rearrange this without changing the enumerations
enum.a = varargin{1};
enum.b = varargin{2};
enum.c = varargin{3};
end
end
function [B, idx] = sort(varargin)
% Overloaded function for the builtin sort() function
t = varargin{1};
varargin{1} = string(varargin{1}); % Using varargin allows us to still pass arguments like sort order "descend" into the builtin function
[~, idx] = sort(varargin{:}); % Sort based on the enum names (varargin{1})
B = t(idx);
end
end
end
I chose to sort my enumeration based on the alphabetic enum name. You could just as easily change it to sort on something like peroperty 'a', by using:
function [B, idx] = sort(varargin)
t = varargin{1};
varargin{1} = varargin{1}.a;
[~, idx] = sort(varargin{:}); % Sort based on the enum 'a' properties
B = t(idx);
end
The cool thing is that a structure like this allows you to do things like:
>> myGreatEnum.mGE2.a
ans =
4
or something like:
>> events = [myGreatEnum.mGE2; myGreatEnum.mGE3; myGreatEnum.mGE2]
>> events(1).a
ans =
4
Anyways, now that the sort() function is overloaded to sort on the enum names (mGE1, mGE2, mGE3, etc....), we can call sort(), or even unique():
>> events = [myGreatEnum.mGE2; myGreatEnum.mGE3; myGreatEnum.mGE2] % Creating the array like you had
events =
3x1 myGreatEnum enumeration array
mGE2
mGE3
mGE2
>> sort(events)
ans =
3x1 myGreatEnum enumeration array
mGE2
mGE2
mGE3
>> unique(events)
ans =
2x1 myGreatEnum enumeration array
mGE2
mGE3
we can even get some of the extended sort() capabilites, like passing in arguments, or getting the indices
>> sort(events, 'descend')
ans =
3x1 myGreatEnum enumeration array
mGE3
mGE2
mGE2
>> [B, I] = sort(events, 'descend')
B =
3x1 myGreatEnum enumeration array
mGE3
mGE2
mGE2
I =
2
1
3
Pretty cool! I understand this post may be a little late, but hopefully it will help someone in the future. :)
Catégories
En savoir plus sur Shifting and Sorting Matrices dans Centre d'aide et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!