Sorting a custom enumeration
显示 更早的评论
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{:});
采纳的回答
更多回答(1 个)
rmiku
2021-7-15
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. :)
类别
在 帮助中心 和 File Exchange 中查找有关 Shifting and Sorting Matrices 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!