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

34 vues (au cours des 30 derniers jours)
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?

Réponse acceptée

teeeeee
teeeeee le 13 Mai 2020
Modifié(e) : teeeeee le 13 Mai 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

Plus de réponses (1)

Sindar
Sindar le 13 Mai 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 commentaire
teeeeee
teeeeee le 13 Mai 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.

Connectez-vous pour commenter.

Produits

Community Treasure Hunt

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

Start Hunting!

Translated by