I need to acces data by string index, like table('one') %returns 1. Is there such a data structure in MATLAB? How is it implemented?
-
1(also cross-duplicate of http://www.mathworks.com/matlabcentral/answers/21130-dictionaries-of-hashtables-in-matlab) – Franck Dernoncourt Mar 24 '12 at 10:45
3 Answers
In recent versions of MATLAB, there's the containers.Map
data structure. See MATLAB Map containers for more. This removes some of the restrictions when using STRUCTs. For example
c = containers.Map
c('foo') = 1
c(' not a var name ') = 2
keys(c)
values(c)

- 1,640
- 1
- 13
- 26

- 23,676
- 2
- 38
- 40
A structure can be used as a sort of hash table:
>> foo.('one')=1
foo =
one: 1
>> foo.('two')=2;
>> x = 'two';
>> foo.(x)
ans =
2
To query whether a structure contains a particular field (key), use isfield
:
>> isfield(foo,'two')
ans =
1
The disadvantage of this scheme is that only strings that are also valid Matlab variable names can be used as keys. For instance:
>> foo.('_bar')=99;
??? Invalid field name: '_bar'.
To get around this restriction, use one of the solutions in the question linked by Oli.

- 14,428
- 8
- 54
- 58
-
Another disadvantage of this approach is that the names of the keys have to be less than `namelengthmax` (63) characters – rhombidodecahedron Apr 23 '15 at 19:20
Just to add to the previous answers (could not comment on the other good answers) : a struct lookup like this:
s={};
s.abc = 1; %insert a value in the struct, abc is your lookup hash
out = s.abc; % read it back
The actual read back of the value is about 10 times faster with a struct than using a container. Full test code as follows if interesting
function s=test_struct_lookup_hash_speed
%% test how a struct lookup speed works vs container, interesting
s = {}; % hash table
v = {}; % reverselookup table for testing
nHashes = 1E4; % vary this to see if read speed varies by size (NOT REALLY)
nReads = 1E6;
fprintf('Generating hash struct of %i entries\n', nHashes);
tic
for i = 1:nHashes
hashStr = md5fieldname(randi(1E8));
s.(hashStr) = i;
v{end+1} = hashStr; %reverselookup
end
toc
fprintf('Actual HashTable length (due to non unique hashes?): %i, and length of reverse table: %i\n',length(fieldnames(s)), length(v) );
fprintf('Reading %i times from a random selection from the %i hashes\n', nReads, nHashes);
vSubset = [ v(randi(nHashes,1,3)) ];
for i = 1:length(vSubset)
hashStr = vSubset{i};
% measure read speed only
tic
for j = 1:nReads
val = s.(hashStr);
end
toc
end
%% test CONTAINERS
fprintf('Testing Containers\n');
c = containers.Map;
fprintf('Generating hash struct of %i entries\n', nHashes);
tic
for i = 1:nHashes
hashStr = md5fieldname(randi(1E8));
c(hashStr) = i;
v{end+1} = hashStr; %reverselookup
end
toc
fprintf('Reading %i times from a random selection from the %i hashes\n', nReads, nHashes);
vSubset = [ v(randi(nHashes,1,3)) ];
for i = 1:length(vSubset)
hashStr = vSubset{i};
% measure read speed only
tic
for j = 1:nReads
val = c(hashStr);
end
toc
end
%% Get a valid fieldname (has to start with letter)
function h=md5fieldname(inp)
h = ['m' hash(inp,'md5')];
end
end

- 51
- 5