Reading Data from container.Map Objects

I have created a container.Map object to store a structure as the value for a given key. The structure has two fields, the date which is a number and a remark for each date. While I could store this as a cell array (due to the different variable types), I like to use structures as it seems to help make the code more readable. I can populate the Map object with the data, unfortunately, when I try to list all of the remarks for a given key, it only returns one entry. What is the correct way to get a list of all the remarks for a given key?
I am running Matlab 8.1.0.604 (R2013a) with Java version 1.6.0_17-b04
Example code is as follows
% Create a new Map object
a = containers.Map;
% Create some silly data to store in it
times = datenum(2013, 1, 1, 0, 0, 0):1:datenum(2013, 1, 10, 0, 0, 0);
remarks = repmat({'Test String'}, 10, 1);
tmp = struct('Time', times, 'Remark', remarks);
% Insert the data into three different keys
a('One') = tmp;
a('Two') = tmp;
a('Three') = tmp;
% Now lets try to list all of the remarks associated with 'Two'
a('Two').Remark
I would like to be able to do something like:
{tmp.Remark}'
ans =
'Test String'
'Test String'
'Test String'
'Test String'
'Test String'
'Test String'
'Test String'
'Test String'
'Test String'
'Test String'
I would like to replace the tmp. in the last command to something like
{a('Two').Remark}'
When I do that I only get one line back. Thanks for any help on this.

 Accepted Answer

I think I got it while writing the comment above.
v = a('Two')
Returns a 10x1 struct. If you look at the output from
v.Time
you'll see ans 10 times, each time with all 10 values.
If you look at:
v.Remark
You'll see test string printed for ans 10x. What is happening is containers.Map's subsref is only extracting the last value since it is not supported for cells or structs. This is just like it would appear at the command line:
y = v.Remark
z = v.Time
Either way, I think this is a fair enhancement request. Why do you want to nest structures inside of a containers.Map object?

3 Comments

Well, as far as the nesting of structures... I have some data that is conveintly indexed by a track identifier. That is my key. Then for each of these there are times and remarks. Since the time is stored as a number and the remarks as a string I am left with only two options, store as a struct array or a cell array. (I guess neither are explicitly supported in the containters.Map regime) I like using struct arrays because it makes my code more readable since I can reference things by a name instead of a number. (Granted, I could use something like C defines for the numbers). But that is my justificaiton. To be honest, the best that I have found so far is to define a custom class to hold the information so that I can control how the accessor method returns the results. As an example...
theTimes = [myarray.Times];
can just be written as
theTimes = myClass.Time;
But, the wrapping brackets are ok...
Are you going to push the request forward or do you need me to place the enhancement request?
The OOP approach is that you suggest above is what I would recommend.
Alternatively, if containers.Map is not sealed, you could inherit from it and then overload subsref to support structs and cells.

Sign in to comment.

More Answers (1)

per isakson
per isakson on 16 Jul 2013
Edited: per isakson on 16 Jul 2013
This looks like a bug to me (R2012a). Either a('Two').Remark should return an error message or the list of ten strings (as you expect). But it should not return only the first string.
I fail to find anything in the documentation on
a('Two').Remark
It might not be supported to address a field of a structure, which is returned by a map-object, this way? Remains
z = a('Two');
z.Remark

5 Comments

It is true that assigning the return of the Map request to an intermediate variable does work, but not ideal. Possibly we should try to get some guidance from the Matlab team on this one. It seems to me that what I want to do is something that should be allowed...
Also, it appears that structs and cells aren't supported for the valueType here:
This could be what is causing the problem, the struct is returned and containers.Map only looks at the first element. It is still strange that it works with Time, though the above could explain that.
I took a look at the link that you passed for the documentation. I do not understand how the description of valueSet limits the storable data type. Additionally, looking at the description of vType further down the page I see "any" as an option. (Plus there is a typo in that description... It should be "data type for the values" instead of "data type for the keys")
After some more looking at the valueSet, it states that it will store any class that support 1 x n values. That means that it should also support struct arrays which is exactly what I am attempting to store.
Ahhh, looking at the beginning text of the doc page it states "Values can be scalar or nonscalar arrays." But to be honest, I am not sure what classifies as a nonscalar array...
I think you're misinterpreting the doc, which I agree is kind of heavy:
vType
String that specifies the data type for the keys. Possible valuesare 'any', 'char', 'logical', 'double', 'single', 'int8', 'uint8', 'int16', 'uint16', 'int32', 'uint32', 'int64',or 'uint64'.
Default: 'any' when you create an empty Map objector when you specify values of different sizes or types, otherwisedetermined by the data type of valueSet
The 'any', at least the way I'm understanding it (which might be incorrect!), is implying that you can combine any of the above classes, e.g. uint64 and double. It does not mean that any object or class can be stored.
And thanks for pointing out the typo, I'll report that to our doc team :)

Sign in to comment.

Categories

Products

Community Treasure Hunt

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

Start Hunting!