Placing a structure within a map container - or is there a different, more suitable way to store this type of data?

47 views (last 30 days)
I have some data associated with several "labels" ('Jan','Feb','Mar', for example), and for each of these labels there are multiple data types (numeric arrays, strings, datetime, etc) for each.
I would like to access the data by specifying the label itself, so I don't have to keep track of any integer indices. I have recently discovered map containers, and tried to implement it in this case by using my "labels" as the keys in the map:
keys = {'Jan','Feb','Mar'};
data_map = containers.Map('KeyType','char','ValueType','any');
% loop over keys and put some data in the map
for k = 1:length(keys)
data_struct.prices = rand(1,5); % create some dummy numbers
data_struct.description = 'HIGH'; % create a dummy label
% place the structure in the map at the relevant key
data_map(keys{k}) = data_struct;
% delete ready for next iteration of the loop
clear data_struct
end
This works nicely, because the structure object is able to handle all the different data types, and I can very compactly and nicely access my data without any integers using:
data_map('Feb').description
My Problem
1) I feel like I am not using it in the correct way, because I have had to use the temporary structure data_struct inside the loop.
2) Additionally, later on I would now like to add an extra field to the structure associated with one of the keys, and would ideally do something like the following for example:
data_map('Feb').temperature = rand(1,8);
This gives the following error:
Only one level of indexing is supported by a containers.Map.
The only way I have been able to do it is to create a temporary structure, which is ugly and cumbersome:
temp_struct = data_map('Feb');
temp_struct.temperature = rand(1,8);
data_map('Feb') = temp_struct;
clear temp_struct
disp( data_map('Feb').temperature )
Is there a better way to store this type of data, append to it afterwards, and still access it nicely by a key name?

Accepted Answer

teeeeee
teeeeee on 13 May 2020
Edited: teeeeee on 13 May 2020
Thanks to Sindar for the suggestion of using tables. I have since become aware of an alternative way to do this, which I think is worth showing as a seperate answer for reference.
This way allows to omit completely any temporary struct variables (as does Sindar's method), but I think is a litlte easier to think how the data is organised:
keys = {'Jan','Feb','Mar'};
data_map = containers.Map('KeyType','char','ValueType','any');
% loop over keys and put some data in the map
for k = 1:length(keys)
% Define some dummy variables
prices = rand(1,6); % a numeric array variable type
description = 'HIGH'; % a character array variable type
% Associate a structure with each key, with variables attached to the various fields
data_map(keys{k}) = struct('prices',prices,...
'description',description);
end
% Add a new field, temperature, to the struct object associated with the key 'Feb'
temperature = rand(1,2);
data_map('Feb') = setfield(data_map('Feb'),'temperature',temperature);
This yields the following for the 'Feb' key for example:
data_map('Feb')
% struct with fields:
% prices: [0.9237 0.6537 0.9326 0.1635 0.9211 0.7947]
% description: 'HIGH'
% temperature: [0.7673 0.6712]
And allows me to nicely access the data with the simple commands:
data_map('Feb').prices
data_map('Feb').description
data_map('Feb').temperature

More Answers (1)

Sindar
Sindar on 13 May 2020
You can give tables row names so they are indexible that way:
keys = {'Jan','Feb','Mar'};
n_keys = length(keys);
data_table = table(rand(n_keys,5),repmat('HIGH',[n_keys 1]),'VariableNames',{'prices';'description'},'RowNames',keys);
>> data_table('Jan',:)
ans =
1×2 table
prices description
_______________________________________________________ ___________
Jan 0.70605 0.046171 0.69483 0.034446 0.76552 HIGH
>> data_table{'Jan','description'}
ans =
'HIGH'
  1 Comment
teeeeee
teeeeee on 13 May 2020
Thanks for the answer. I hadn't considered doing it with tables. I have also provided an alternative way to do it in a separate answer. It seems a little unusual (at least to me) to have a long vector running horizontally within a single table column (as you have done with "prices"). However, it does the job. Thanks again.

Sign in to comment.

Products

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!