Dictionary / Map with array as key
34 views (last 30 days)
Show older comments
Hi there,
I'm looking for a way to initialize a map with an array as Key.
I am thinking of something like
map = containers.Map;
state = {1,2};
map(state) = 0;
However, the last line fails with
Error using containers.Map/subsasgn
Specified key type does not match the type expected for this container.
Is there any way I can initialize a Map with an array (not converted to char) as keys?
Or is there any other appropriate data structure for doing this?
Looking forward to your ideas;)
2 Comments
Answers (3)
Mehmed Saad
on 23 Jun 2020
Edited: Mehmed Saad
on 27 Jun 2020
EDIT: First Answer is replaced
I donot understand why you dont want to go on characters. see the code below
M = containers.Map('KeyType','char','ValueType','double');
%% Single Key
key1 = [1.8 2.0 0.005];
valueSet = 327.2;
%% array key encoder
keySet = key_enc(key1);
M = containers.Map(keySet,valueSet);
%% array key decoder
key1_dbl = key_dec(M.keys);
assert(isequal(key1_dbl,key1));
where key_enc is double array to character converter. It basically converts double precision to hexadecimal (so that we dont lose any data due to rounding off)
Similarly key_dec is character to array double converter in order to retreive the key
For 2D Array
M = containers.Map('KeyType','char','ValueType','double');
%% More than 1
key1 = [1.8 2.0 0.005;4 5 6];
valueSet = [327.2 550];
%% array key encoder
keySet = key_enc(key1)
M = containers.Map(keySet,valueSet);
%% array key decoder
key1_dbl = key_dec(M.keys);
assert(isequal(key1_dbl,key1));
Point to remember
- a row is a complete key (i.e. a single row vector is considered as 1 key)
- key must be double precision (or any other 64 bit type)
- if you provide a 2D matrix, the number of rows represent number of keys
- key_inc can take both 1D and 2D input, it will return scalar output for 1D row vector. It's output type is cell array of character vectors
- key_dec take cell array of character vector as input and will return the double key in that format
Functions
Key Encoder
function key1_char = key_enc(key1)
[m,n] = size(key1);
key1_char=repmat({char(ones(1,16*n))},m,1);
tmp = num2hex(key1);
for ii=1:m
key1_char{ii,:} = reshape((tmp(ii:m:end,:).'),1,16*n);
end
end
Key Decoder
function key1_dbl = key_dec(key1_char)
m = numel(key1_char);
n = numel(key1_char{1});
key1_dbl = zeros(m,n/16);
for ii=1:m
key1_dbl(ii,:) = transpose(hex2num(transpose(reshape(key1_char{ii},16,n/16))));
end
end
Edit:
it is not necessary that assert works everytime because map gives sorted key out
For example
rng(2017)
key1 = randn(2,10);
valueSet =[1 2];
%% array key encoder
keySet = key_enc(key1)
keySet =
2×1 cell array
{'c00151bd6e3dafe9bfcefd29436d4...7b0bfe72b879a67bbee'}
{'3ff0c59e4de6586abff94c4bcb1ceb...ba03fd58526d0d66e84'}
Now see that they are not sorted in ascending order while
M = containers.Map(keySet,valueSet);
M.keys
ans =
1×2 cell array
{'3ff0c59e4de6586abff94c4bcb1ceb433fd72f384820035ebff29c1…'} {'c00151bd6e3dafe9bfcefd29436d4de93fe6733364db1b1fbfe17d1…'}
so if now you check them error will occur (assertion failed)
5 Comments
Walter Roberson
on 26 Jun 2020
No. Keys can be numeric scalars or character vectors or string() scalars, and cannot be cells and cannot be numeric vectors or non-scalar string objects.
Walter Roberson
on 26 Jun 2020
It isn't nice but ...
A container.Map can be a value. So you can create a top level container.Map that has a key that is 1.8, and the associated value is a second container.Map . The second container you would have a key that is 2.0 and associated value is a third container.Map . That third container.Map would have a key 0.005 and value would be whatever you were trying to associate as a value for key1 .
I would not expect this to be efficient. For efficiency, you would probably be better of doing something like an MD5 of key1 and use that as the key. Or see https://www.mathworks.com/matlabcentral/answers/534528-how-to-save-serialize-matlab-variables-to-a-byte-string#answer_439768 with the idea being that you would apply that to key1 and use the result as the key -- the advantage there would be that you would be able to look at the key list and deserialize the key list entries to find out what the resulting numeric keys were.
0 Comments
See Also
Categories
Find more on Data Type Identification in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!