Map2 - enhanced map class

by

 

Map2 enhance the functionality of the built-in containers.Map class.

Map2
classdef Map2 < containers.Map & handle
    %MAP2 constructs a Map2 object.
    %   The Map2 object is a subclass of the built-in containers.Map class. 
    %   It is a data structure which contains of key-value pairs. Map2 enhance
    %   the functionality of the built-in containers.Map class. It provides
    %   a few extra methods and allows you to use indexing in order to get
    %   specific values from the container. Also a bidirectional use of 
    %    key-value pairs is supported (like Boost.Bimap library).
    %
    %   Map2 object can be indexed by using curly brackets {range1,range2}. 
	%	It returns a cell array of values or scalar value of Map2 given range 
	%	(range1,range2). range1 refers to position of the value set and 
	%	range2 refers to position inside a value set. range2 can be omitted 
	%	if not needed. 
    %
    %   Look at the built-in containers.Map class documentation for more 
    %   info about how to properly construct a Map2 object and what 
    %   properties/methods it includes.   
    %
    %   Examples:
    %       myMap = Map2({'West Germany','Argentina','Italy','England'},...
    %                                {1,2,3,4}); 
    %       fprintf(1,'The number of coutries is %d\n',myMap.length);
    %       fprintf(1,'The winner is %s\n',myMap.right_at(myMap.right_find(1)))
    %       fprintf(1,'Countries names ordered by their final position:\n')
    %       for k = 1:myMap.length
    %           fprintf(1,'%s)\t%s\n',num2str(myMap{myMap.right_find(k)}),myMap.right_at(myMap.right_find(k)))
    %       end
    %       fprintf(1,['Countries names ordered alphabetically along',...
    %                  ' with their final position:\n']);
    %       for k = 1:myMap.length
    %           fprintf(1,'%s ends in position %s\n',myMap.right_at(k),num2str(myMap{k}))
    %       end
    %
    %       myMap = Map2({'Frequency','Impedance','Phase'},...
    %       {[1 10 1e2 1e3 1e4 1e5],[1 2 4 8 16 32],[90 90 89 85 60 20]});
    %       myMap = myMap.addSets({'Resistance','Inductance'},{[0.2 0.3 0.5 0.7 1.2 1.75],...
    %                             [1.1e-4 1.05e-4 0.9e-4 0.7e-4 0.4e-4 0.1e-4]});
    %       figure(1)
    %       plot(cell2mat(myMap{myMap.find('Frequency'),1:numel(myMap('Frequency'))-2}),...
    %            cell2mat(myMap{3,1:4}),'linew',2);           
    %       xlabel(myMap.right_at(1));
    %       ylabel(myMap.right_at(3));
    %       figure(2)
    %       dataSets = myMap{[4,3]};    
    %       plot(cell2mat(dataSets(:,1)),cell2mat(dataSets(:,2)),'linew',2);           
    %       xlabel(myMap.right_at(4));
    %       ylabel(myMap.right_at(3));
    %
    %
    %		% Calculate the number of all values in the container.
    %       sum(cell2mat(cellfun(@(x) numel(x),myMap{1:myMap.length},'uni',false)))
    %
    %       % Get one element from value set    
    %       elem  = myMap{2,5}
    %       elem  = myMap.right_at(2,3)
    %        
    %   Map2 public properties:
    %       Inherited from containers.Map class:
    %       KeyType     -   Type of key used by this instance of Map.
    %       ValueType   -   Type of value used by this instance of Map.
    %       Count       -   Number of key-value pairs in Map.
    %
    %
    %   Map2 public methods:
    %       clear       -   Removes all the key-values pairs from the data
    %                       structure.
    %       find        -   Return an index of the given key argument. If the key
	%						is not found then index will empty.
    %       addSets     -   Return a new Map2 object which size has been
    %                       increased by the given key-value pairs.
    %       right_find  -   Return an index of the given key argument. Index look up is done
	%						switching key-value pairs (Map(X,Y) => Map(Y,X)). If the key
	%						is not found then index will empty.
	%		right_at	- 	Return an array of values(cell or scalar) of Map2 given range 
	%						(range1,range2). Key-value pairs have been switched (Map(X,Y) => Map(Y,X))  
	%						Where range1 refers to position of the value set and range2 
	%						refers to position inside a value set. range2 can be omitted 
	%						if not needed. 
	%
    %       Inherited from containers.Map class:    
    %       isKey       -   Determine whether Map2 contains given key.
    %       keys        -   Return cell array of keys of Map2.
    %       values      -   Return cell array of values of Map2.
    %       remove      -   Remove key-value pairs from Map2.
    %       size        -   Return size of Map2.
    %       length      -   Return length of Map2.  This is the number of 
    %                       key-value pairs in Map2.
    %       isempty     -   Determine if Map2 contains any data.   
    %
    %
    %   See also containers.Map
    %
    %   Copyright Mikko Leppänen 2013
    %
    %   Version history:
    %       13/02/2013 - first release 
    
    methods
        function obj = Map2(varargin)
            obj = obj@containers.Map(varargin{:});
        end
        function obj = clear(obj)
            obj = obj.remove(obj.keys);
        end
        function ind = find(obj,key)
            ind = find(cell2mat(cellfun(@(x) isequal(x,key),obj.keys,'uni',false)));
        end
        function varargout = subsref(obj,s)
           switch s(1).type
               case '.'
                   if strcmp(s(1).subs,'right')
                       varargout{1} = right_find(varargin);
                   else
                       varargout{1} = subsref@containers.Map(obj,s);
                   end
               case '()'
                   varargout{1} = subsref@containers.Map(obj,s);
               case '{}'
                   if numel(s(1).subs) > 2 || isempty(s(1).subs)
                       varargout{1} = [];
                       return;
                   end
                   if numel(s(1).subs) == 2
                       validateattributes(s(1).subs{1},{'numeric'},{'vector','>',0,'<=',numel(obj.values)});
                       values = {};
                       for k = s(1).subs{1}
                           validateattributes(s(1).subs{2},{'numeric'},{'vector','>',0,'<=',numel(obj.values{k})});
                           if numel(s(1).subs{2}) == 1 && numel(s(1).subs{1}) == 1
                                varargout{1} =  obj.values{k}(s(1).subs{2});
                                return;
                           else
                                values{end+1} = obj.values{k}(s(1).subs{2});
                           end
                       end
                       varargout{:} = values;
                   else
                       validateattributes(s(1).subs{:},{'numeric'},{'vector','>',0,'<=',numel(obj.values)});
                       if numel(s(1).subs{:}) == 1
                           varargout{1} = obj.values{s(1).subs{:}};
                       else
                           varargout{:} = {obj.values{s(1).subs{:}}};
                       end
                   end
           end 
        end
        
        function obj = addSets(obj,keySet,valueSet)
            obj = [obj;containers.Map(keySet,valueSet)];
        end
        
        function ind = right_find(obj,key)
            ind = find(cell2mat(cellfun(@(x) isequal(x,key),obj.values,'uni',false)));
        end
        function varargout = right_at(obj,varargin)
            if ~isempty(varargin) && numel(varargin) < 3
                validateattributes(varargin{1},{'numeric'},{'vector','>',0,'<=',numel(obj.values)});
                range1 = varargin{1};
                if numel(varargin) == 2
                   values = {};
                   range2 = varargin{2};
                   for k = range1
                       validateattributes(range2,{'numeric'},{'vector','>',0,'<=',numel(obj.keys{k})});
                       if numel(range2) == 1 && numel(range1) == 1
                            varargout{1} =  obj.keys{k}(range2);
                            return;
                       else
                            values{end+1} = obj.keys{k}(range2);
                       end
                   end
                       varargout{:} = values;
                else
                   if numel(range1) == 1
                       varargout{1} = obj.keys{range1};
                   else
                       varargout{:} = {obj.keys{range1}};
                   end
               end
            else
                varargout{1} = [];
            end  
        end
        function n = numel(varargin)
            n = 1;
        end
    end
end

Contact us