Customize Parentheses Indexing for Mapping Class
This example shows how to customize parentheses indexing for a class. The
MyMap
class stores strings ("keys") that are associated with elements
("values") of a cell array. The class inherits from
matlab.mixin.indexing.RedefinesParen
to define custom behavior for
indexing with parentheses. The class supports three customized indexing operations:
returns the value associated with the key.instanceName
("keyName
")
adds a new key and associated value.instanceName
("keyName
") =value
deletes the key and its associated value.instanceName
("keyName
") = []
The full code for the class and its helper function, validateKeys
,
is available at the end of the example.
MyMap Class | Explanation |
---|---|
classdef MyMap... < matlab.mixin.indexing.RedefinesParen | Define |
properties (Access = private)
Keys (:,1) string
Values (:,1) cell
end | The private properties |
methods (Static, Access = public) function obj = empty(varargin) if nargin == 0 obj = MyMap(string.empty(0,1),cell.empty(0,1)); return; end keys = string.empty(varargin{:}); if ~all(size(keys) == [0, 1]) error("MyMap:MustBeEmptyColumnVector",... "The only supported empty size is 0x1."); end obj = MyMap(keys,cell.empty(varargin{:})); end end | Implementation of the static, abstract method |
methods (Access = public) function obj = MyMap(keys_in,values_in) if nargin == 0 obj = MyMap.empty(0,1); return; end narginchk(2,2); if ~all(size(keys_in) == size(values_in)) error("MyMap:InputSizesDoNotMatch",... "The sizes of the input keys and values must match."); end obj.Keys = keys_in; obj.Values = values_in; end end | The constructor accepts the keys and values as input arguments and ensures the arrays are the same size. |
function keys = getKeys(obj) keys = obj.Keys; end function values = getValues(obj) values = obj.Values; end | Two public methods provide read access to the keys and values. |
function varargout = size(obj,varargin) [varargout{1:nargout}] = size(obj.Keys,varargin{:}); end function C = cat(dim,varargin) error("MyMap:ConcatenationNotSupported",... "Concatenation is not supported."); end function lastKey = end(~,~,~) error("MyMap:EndNotSupported",... "Using end with MyMap objects is not supported."); end | Implementation of the abstract methods |
methods (Access = private) function [keyExists,idx] = convertKeyToIndex(obj,keyCellArray) arguments obj keyCellArray cell {validateKeys} end requestedKey = keyCellArray{1}; idx = find(contains(obj.Keys,requestedKey)); keyExists = ~isempty(idx); end end | The |
methods (Access = protected) function varargout = parenReference(obj,indexOp) [keyExists,idx] = convertKeyToIndex(obj,indexOp(1).Indices); if ~keyExists error("MyMap:KeyDoesNotExist",... "The requested key does not exist."); end if numel(indexOp) == 1 nargoutchk(0,1); varargout{1} = obj.Values{idx}; else % Additional operations [varargout{1:nargout}] = obj.Values{idx}.(indexOp(2:end)); end end | Implementation of the abstract method
|
function obj = parenAssign(obj,indexOp,varargin) indicesCell = indexOp(1).Indices; [keyExists,idx] = convertKeyToIndex(obj,indicesCell); if numel(indexOp) == 1 value = varargin{1}; if keyExists obj.Values{idx} = value; else obj.Keys(end+1) = indicesCell{1}; obj.Values{end+1} = value; end return; end if ~keyExists error("MyMap:MultiLevelAssignKeyDoesNotExist", ... "Assignment failed because key %s does not exist",... indicesCell{1}); end [obj.Values{idx}.(indexOp(2:end))] = varargin{:}; end | Implementation of the abstract method |
function obj = parenDelete(obj,indexOp) [keyExists,idx] = convertKeyToIndex(obj,indexOp(1).Indices); if keyExists obj.Keys(idx) = []; obj.Values(idx) = []; else error("MyMap:DeleteNonExistentKey",... "Unable to perform deletion. The key %s does not exist.",... indexOp(1).Indices{1}); end end | Implementation of the abstract method |
function n = parenListLength(obj,indexOp,indexingContext) [keyExists,idx] = convertKeyToIndex(obj,indexOp(1).Indices); if ~keyExists if indexingContext == matlab.indexing.IndexingContext.Assignment error("MyMap:MultiLevelAssignKeyDoesNotExist", ... "Unable to perform assignment. Key %s does not exist",... indexOp(1).Indices{1}); end error("MyMap:KeyDoesNotExist",... "The requested key does not exist."); end n = listLength(obj.Values{idx},indexOp(2:end),indexingContext); end end | Implementation of the abstract method
|
Expand for Class and Helper Function Code
Save the code for MyMap
and validateKeys
in your
MATLAB path. Create an instance of MyMap
with an initial list of
three keys and values.
map = MyMap(["apple","cherry","orange"],{1,3,15});
Use the map("
syntax to return
the value corresponding to a specific key.keyName
")
map("cherry")
ans = 3
Use the map("
to add a new key to the array.keyName
") =
value
map("banana") = 2; map("banana")
ans = 2
Use the map("
to delete a
key and its associated value from the array. Confirm the key is no longer in the
array.keyName
") = []
map("orange") = []; map("orange")
Error using MyMap/parenReference (line 88) The requested key does not exist.
See Also
matlab.mixin.indexing.RedefinesParen
| matlab.indexing.IndexingOperation