Code covered by the BSD License  

Highlights from
dict

from dict by Doug Harriman
General purpose data storage object

dict
%DICT  Dictonary data storage.  Stores data by key/value pairs.
% Creates a key/value dictionary similar to the DICT object in Python.
% Keys and values may be any valid Matlab data type.
% 
% Examples:
%   x=dict;          % Create dictionary object
%   x(12)='hello';   % Store value.
%   x('hi')=[1 2 3]; % Store value.
%
%   x('hi')          % Lookup value
%     ans =
%        1 2 3
%
%   x(12)            % Lookup value
%     ans = 
%   hello
%
%   lookup(x,12)     % Lookup value
%     ans = 
%   hello
%
%  Other methods:
%    KEYS    - Returns cell array of all keys.
%    VALUES  - Returns cell array of all values.
%
%    ISEMPTY - Returns true if dictionary is empty.
%    LENGTH  - Returns number of elements stored in dictionary.
%    ISKEY   - Determines if a key exists in dictionary.
%    INDEX   - Returns index of key in key array.
%
%    PLUS    - Combines two dictionaries.
%    MINUS   - Creates dictionary of unique keys.
%    RMKEY   - Removes key/value pair from dictionary.
%
%    RENAME  - Renames a key.
%
% Credits: Inspired by and based on LOOKUPTABLE by Dan Cohn, available on
%          Matlab Central:
%          http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=19381&objectType=file
%

% Written by: Doug Harriman (doug <dot> harriman <at> gmail <dot> com)
% 25-Apr-08 - Added RENAME.
% 20-Apr-08 - '.' access to methods working.  Allethods have help text.
%             Added '+' and '-' methods to composite DICT's.
% 03-Apr-08 - More methods to make more similar to Python dict object.
% 02-Apr-08 - Initial version.

classdef dict < handle

    properties (SetAccess=protected)
    
        % Cell arrays to hold keys and values of any Matlab data type
        key   = {};
        value = {};
        
    end % properties - protected
    
    methods 

        function val = subsref(obj,ref)
            %DICT/SUBSREF Subscript referencing for DICT objects.
            %  
            %  See also: DICT
            %

            % Re-implement dot referencing.
            if strcmp(ref(1).type,'.')
                % User trying to access a property or method.
                
                % Property access
                props = fieldnames(struct(obj));
                if ismember(ref(1).subs,props)
                   val = obj.(ref.subs);
                   return;
                end
               
                % Methods access
                if ismember(ref(1).subs,methods(obj))
                    if length(ref) > 1
                        % Call with args
                        val = obj.(ref(1).subs)(ref(2).subs{:});
                    else
                        % No args
                        val = obj.(ref.subs);
                    end
                    return;
                end
                
                % User trying to access something else.
                error(['Reference to non-existant property or method ''' ref.subs '''']);
            end
            
            if ~strcmp(ref.type,'()')
                error('Cell indexing not supported.');
            end

            % Vectorized calls not supported
            if length(ref.subs) > 1
                error('DICT only supports storing key/value pairs one at a time.');
            end
            key = ref.subs{1};

            val = lookup(obj,key);
            
        end % subsref
        
        
        function obj = subsasgn(obj,ref,value)
            %DICT/SUBSASGN  Subscript assignment for DICT objects.
            %
            %  See also: DICT
            %
            
            if ~strcmp(ref.type,'()')
                error('Cell and dot indexing for assignment not supported.');
            end
            
            % Vectorized calls not supported
            if length(ref.subs) > 1
                error('DICT only supports storing key/value pairs one at a time.');
            end
            key = ref.subs{1};

            % Existing or new key?
            idx = index(obj,key);
            if isempty(idx)
                % New
                idx = length(obj.key) + 1;
            end

            obj.key{idx}   = key;
            obj.value{idx} = value;

        end % subsasgn
        
        
        function val = length(obj)
            %DICT/LENGTH  Number of key/value pairs in dictionary.
            %
            %  See also: DICT
            %
            
            val = length(obj.key);
        end
        
        
        function idx = index(obj,key)
            %DICT/INDEX  Find index of a key in the dictionary key array.
            %
            %  See also: DICT
            %
            
            idx = cellfun(@(x)isequal(x,key),obj.key);
            idx = find(idx);
        end % index
        
        
        function [] = disp(obj)
            %DICT/DISP  Display a DICT object.
            %  
            %  See also: DICT
            %
            
            disp(' Dictionary:');
            disp(struct(obj));
        end % disp
        
        
        % DISPLAY 
        function [] = display(obj)
            %DICT/DISPLAY  Display a DICT object.
            %  
            %  See also: DICT
            %
            disp(obj);
        end
        
        
        function val = lookup(obj,key)
            %DICT/LOOKUP  Return a value given a key.
            %
            %  See also: DICT, DICT/INDEX
            %

            % Make sure key exists
            idx = index(obj,key);
            if isempty(idx)
                val = [];
                return;
            end
            
            % Extract value
            val = obj.value(idx);
            val = val{1};
        end

        
        function data = keys(obj)
            %DICT/KEYS  Returns cell array of all keys in a DICT object.
            %
            %  See also: DICT, DICT/VALUES
            %
            
            data = obj.key';
        end % keys

        
        function data = values(obj)
            %DICT\VALUES  Returns cell array of all values in a DICT object.
            %
            %  See also: DICT, DICT/KEYS
            %
            
            data = obj.value';
        end % values

        
        function tf = iskey(obj,keys)
            %DICT/ISKEY  Returns bool array denoting if key(s) exist in dictionary.
            %
            %  See also: DICT, DICT/KEYS
            %
            
            if ~iscell(keys)
                keys = {keys};
            end
            nkeys = length(keys);
            tf    = false(nkeys,1);
            for i = 1:nkeys
                key = keys{i};
                tf(i) = any(cellfun(@(x)isequal(x,key),obj.key));
            end
        end % iskey
        
        
        function obj = rmkey(obj,key)
            %DICT/RMKEY  Removes a key/value pair from a dictionary by key.
            %
            %  See also: DICT, DICT/ISKEY
            % 
            
            idx = index(obj,key);
            obj.key(idx)   = [];
            obj.value(idx) = [];
            
            % Make the display look nice
            if isempty(obj.key)
                obj.key   = {};
                obj.value = {};
            end
        end % rmkey

        
        function tf = isempty(obj)
            %DICT/ISEMPTY  Returns true if dictionary isempty.
            %
            %  See also: DICT, DICT/KEYS
            %
            
            tf = isempty(obj.key);
        end % isempty
        
        
        function obj1 = plus(obj1,obj2)
            %DICT/PLUS  Creates composite dictionary.
            %  DICT1+DICT2 returns a dictionary composed of key value pairs
            %  from both DICT1 and DICT2.  If both dictionaries contain the
            %  same key, the value stored in DIC1 will be used.
            %
            %  See also: DICT, DICT/MINUS, DICT/KEYS, DICT/ISKEY
            %
            
            % Error check inputs
            error(nargchk(2,2,nargin));
            if ~isa(obj2,'dict')
                error('Both inputs must be DICT objects.');
            end
            
            % Look for key collisions
            idx = obj1.iskey(obj2.keys);
            
            % Tack on unique keys and values to x.
            obj1.key   = {obj1.key{:} obj2.key{~idx}};
            obj1.value = {obj1.value{:} obj2.value{~idx}};
            
        end % plus

        
        function obj1 = minus(obj1,obj2)
            %DICT/MINUS  Creates dictionary of unique keys.
            %  DICT1-DICT2 returns a dictionary composed of key value pairs
            %  which have keys that only exist in DICT1.
            %
            %  See also: DICT, DICT/PLUS, DICT/KEYS, DICT/ISKEY
            %

            % Error check inputs
            error(nargchk(2,2,nargin));
            if ~isa(obj2,'dict')
                error('Both inputs must be DICT objects.');
            end
            
            % Look for key collisions
            idx = ~obj2.iskey(obj1.keys);
            
            % Tack on unique keys and values to x.
            obj1.key   = obj1.key(idx);
            obj1.value = obj1.value(idx);

        end % minus

        function obj = rename(obj,key_old,key_new)
            %DICT/RENAME  Renames a key.
            %  RENAME(DICT,KEY_OLD,KEY_NEW) 
            %
            %  See also: DICT, DICT/ISKEY
            % 
            
            idx = index(obj,key_old);

            if isempty(idx)
                return;
            end
               
            obj.key{idx} = key_new;
            
        end % rename

        
    end % methods
    
end % classdef 

Contact us at files@mathworks.com