Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Missing a couple of basic (and very necessary) features in containers.Map

238 views
Skip to first unread message

Joao Henriques

unread,
Apr 1, 2010, 12:38:05 PM4/1/10
to
Almost all of my Matlab work is done using arrays, sparse arrays and cell arrays. Only recently have I found a natural application for containers.Map, and I was pretty excited to explore this relatively new tool.

However, a few missing features are making it hard to work with. First, there's no way to create a new, empty Map and specify its KeyType/ValueType -- the Map is initialized with the default types ('char'/'any'), and if I want to index values by 'double' or something, I can't. The annoying workaround is to initialize it with a dummy pair of the types I want, then delete it (hardly elegant, but I can do that while waiting for the fix).

This behavior must be very confusing for someone not willing to dig deeper into the issue, and can be one of the factors that explains the slow adoption of the Map class; since the new user is greeted with an error when trying a simple operation :)

Secondly, the documentation has a section "Modifying a Copy of the Map", which says that Map assignments only take the reference, instead of making a copy. There must be a method to make a copy of the Map (right?); the documentation isn't very helpful in this regard, as copying by value is a pretty standard operation. (I'm not suggesting that the behavior of the assignment operation should be changed, only that a copy method be added or referenced in the docs.)

Also, it seems surprising that character arrays can be hashed, but for instance double arrays cannot. This feature would be very appreciated, although I can live without it of course.

And continuing with the "containers" idea, some algorithms require a vector/cell array that supports fast insertions and deletions (say, a list of active kalman filters for tracking). Right now I'm trying to use the Map for this effect (then do a little benchmarking to see if it's worth it vs. simple vectors/matrices, by saving the memory allocs/deallocs when resizing), but in the future it would be nice to have a List container to complement the Map.

Anyway, just pointing out some issues since with any new feature there's always room for improvement. The first two are essential in my opinion, the last two are just "nice-to-have" 's. Many thanks to the Matlab team for their hard work :)

EBS

unread,
Apr 1, 2010, 6:26:05 PM4/1/10
to
"Joao Henriques" <remove_this_...@hotmail.com> wrote in message <hp2i5d$pj9$1...@fred.mathworks.com>...

> Almost all of my Matlab work is done using arrays, sparse arrays and cell arrays. Only recently have I found a natural application for containers.Map, and I was pretty excited to explore this relatively new tool.
>
> However, a few missing features are making it hard to work with. First, there's no way to create a new, empty Map and specify its KeyType/ValueType -- the Map is initialized with the default types ('char'/'any'), and if I want to index values by 'double' or something, I can't. The annoying workaround is to initialize it with a dummy pair of the types I want, then delete it (hardly elegant, but I can do that while waiting for the fix).

That does seem odd...

>
> This behavior must be very confusing for someone not willing to dig deeper into the issue, and can be one of the factors that explains the slow adoption of the Map class; since the new user is greeted with an error when trying a simple operation :)
>
> Secondly, the documentation has a section "Modifying a Copy of the Map", which says that Map assignments only take the reference, instead of making a copy. There must be a method to make a copy of the Map (right?); the documentation isn't very helpful in this regard, as copying by value is a pretty standard operation. (I'm not suggesting that the behavior of the assignment operation should be changed, only that a copy method be added or referenced in the docs.)

I can't see any doc about this either.

>
> Also, it seems surprising that character arrays can be hashed, but for instance double arrays cannot. This feature would be very appreciated, although I can live without it of course.

Agreed.

>
> And continuing with the "containers" idea, some algorithms require a vector/cell array that supports fast insertions and deletions (say, a list of active kalman filters for tracking). Right now I'm trying to use the Map for this effect (then do a little benchmarking to see if it's worth it vs. simple vectors/matrices, by saving the memory allocs/deallocs when resizing), but in the future it would be nice to have a List container to complement the Map.

Agreed, I've love to have a List, Deque, Stack, Tree, etc :)


>
> Anyway, just pointing out some issues since with any new feature there's always room for improvement. The first two are essential in my opinion, the last two are just "nice-to-have" 's. Many thanks to the Matlab team for their hard work :)

Please send your feedback directly to Tech Support. Posts to the newsgroup don't have the weight of feedback officially recorded in the bug/enhancement database, which is what is used to prioritize features for implementation.

Cheers!

EBS

unread,
Apr 1, 2010, 6:30:23 PM4/1/10
to
"Joao Henriques" <remove_this_...@hotmail.com> wrote in message <hp2i5d$pj9$1...@fred.mathworks.com>...
> Almost all of my Matlab work is done using arrays, sparse arrays and cell arrays. Only recently have I found a natural application for containers.Map, and I was pretty excited to explore this relatively new tool.
>
>(snip)
> Anyway, just pointing out some issues since with any new feature there's always room for improvement. The first two are essential in my opinion, the last two are just "nice-to-have" 's. Many thanks to the Matlab team for their hard work :)

Here's a post describing a feature that I feel is missing, what do you think?
http://www.mathworks.com/matlabcentral/newsreader/view_thread/244296#627675

If you agree, please contact TMW tech support and ask to add a feature request for this (it might already exist in the database, I can't remember if I called them about it or not).


Hi all,

is there any reason why the following syntax does not work?

>> keys = {'test1' 'test2' 'test3'};
>> values = {1 2 3};
>> myMap = containers.Map(keys,values);
>> dataKeys = {'test1' 'test3'};
>> data1 = myMap(dataKeys{1}) % this works, with a scalar string input.
>> data2 = myMap.values(dataKeys) % this works, but extra typing rel. to below.
>> data3 = myMap(dataKeys) % this does not work.
??? Error using ==> subsref
Specified key type does not match the type expected for this container.

It would seem to be a valid syntax - it's unique from the existing documented syntax and thus could be parsed (because it's a single cell array instead of a scalar), and it would be handy for the user because it's shorter than using the values method and seems very natural.

Joao Henriques

unread,
Apr 1, 2010, 7:51:04 PM4/1/10
to
"EBS " <ericDOT...@gmail.com> wrote in message <hp36ht$knm$1...@fred.mathworks.com>...

> Please send your feedback directly to Tech Support. Posts to the newsgroup don't have the weight of feedback officially recorded in the bug/enhancement database, which is what is used to prioritize features for implementation.

Yes, I'm going to do that just now. This is one of those things that could be extremely handy, and as we develop ever more complex Matlab programs we start to miss some data structures that are common in other languages.

> "Joao Henriques" <remove_this_...@hotmail.com> wrote in message <hp2i5d$pj9$1...@fred.mathworks.com>...

> > And continuing with the "containers" idea, some algorithms require a vector/cell array that supports fast insertions and deletions (say, a list of active kalman filters for tracking). Right now I'm trying to use the Map for this effect (then do a little benchmarking to see if it's worth it vs. simple vectors/matrices, by saving the memory allocs/deallocs when resizing), but in the future it would be nice to have a List container to complement the Map.
>
> Agreed, I've love to have a List, Deque, Stack, Tree, etc :)

Sure, although the Tree could be a bit of a tall order compared to the rest!

List, Deque, Stack -- they can all be collapsed into a single List, with appropriate [push/pop]_[back/front] methods, if it's implemented as a standard doubly-linked-list with back and front pointers. Having just a List would be a big improvement, although first I'd like the Map to receive a little more attention :)

Joao Henriques

unread,
Apr 1, 2010, 7:55:23 PM4/1/10
to
"EBS " <ericDOT...@gmail.com> wrote in message <hp36pv$o34$1...@fred.mathworks.com>...

> It would seem to be a valid syntax - it's unique from the existing documented syntax and thus could be parsed (because it's a single cell array instead of a scalar), and it would be handy for the user because it's shorter than using the values method and seems very natural.

Well, usually, only vectors are used when indexing multiple elements, since each index is a scalar number. Since an index in the context of a Map can be non-scalar, and a "vector" of non-scalar things is a cell array, multiple-indexing requires cell arrays. So yes, it makes sense, although the Map is a very special case in this regard! :)

Bruno Luong

unread,
Apr 2, 2010, 2:38:02 AM4/2/10
to
"Joao Henriques" <remove_this_...@hotmail.com> wrote in message <hp2i5d$pj9$1...@fred.mathworks.com>...
> First, there's no way to create a new, empty Map and specify its KeyType/ValueType -- the Map is initialized with the default types ('char'/'any'), and if I want to index values by 'double' or something, I can't.

This has been the case but in 2010a, initialize empty Map is possible:

m=containers.Map('KeyType', 'double', 'ValueType', 'logical')

m =

containers.Map handle
Package: containers

Properties:
Count: 0
KeyType: 'double'
ValueType: 'logical'

Methods, Events, Superclasses

% Bruno

Joao Henriques

unread,
Apr 2, 2010, 11:08:06 AM4/2/10
to
"Bruno Luong" <b.l...@fogale.findmycountry> wrote in message <hp43ca$mbs$1...@fred.mathworks.com>...

> This has been the case but in 2010a, initialize empty Map is possible:
>
> m=containers.Map('KeyType', 'double', 'ValueType', 'logical')
>
> m =
>
> containers.Map handle
> Package: containers
>
> Properties:
> Count: 0
> KeyType: 'double'
> ValueType: 'logical'
>
> Methods, Events, Superclasses
>
> % Bruno

Nice! Too bad this sort of bug fixes aren't patched back into earlier versions of Matlab (to the best of my knowledge, that is).

Thomas

unread,
Jul 9, 2010, 10:48:04 AM7/9/10
to

> There must be a method to make a copy of the Map (right?); the documentation isn't very helpful in this regard, as copying by value is a pretty standard operation.

I just figured out how to do this and thought I'd share:

>> x = containers.Map();
>> x('hi') = 1234;
>> y = [ x; containers.Map() ];
>> y('hi') = 4321;
>> x('hi')

ans =

1234

So, when you concatenate Map containers, you get a new one that's the union of the two. If you concatenate one with an empty one, you get a copy by value of the first one.

-Thomas

Joao Henriques

unread,
Jul 9, 2010, 12:24:04 PM7/9/10
to
"Thomas " <no.tg...@resc.net> wrote in message <i17cr4$b0v$1...@fred.mathworks.com>...

> So, when you concatenate Map containers, you get a new one that's the union of the two. If you concatenate one with an empty one, you get a copy by value of the first one.

Thanks, that is helpful!

João Henriques

Georgios Papachristoudis

unread,
Oct 1, 2013, 3:26:07 PM10/1/13
to
Brilliant hack! Thanks for sharing!

"Thomas " <no.tg...@resc.net> wrote in message <i17cr4$b0v$1...@fred.mathworks.com>...
>

mlrogers

unread,
Jun 23, 2015, 3:14:08 PM6/23/15
to
"Georgios Papachristoudis " <gio...@gmail.com> wrote in message <l2f7kf$6mk$1...@newscl01ah.mathworks.com>...
Nested maps are still passed as pointers, so we need a way to do deep copies.

Marie

unread,
Oct 27, 2015, 1:14:08 PM10/27/15
to
Thomas's concatenation can be extended inside a deepcopy function. It would be more elegant to derive a new class that supports a copy function, but this should do the trick:

function newmap = map_deepcopy(map)
% newmap = map_deepcopy(map)
% Create a copy of a map that has maps nested within it.

% hack to create a copy of the current level map of the same type
dummy = containers.Map('KeyType', map.KeyType, ...
'ValueType', map.ValueType);
newmap = [map; dummy];

% Any nested maps in newmap still point to the original,
% let's copy them as well.

keyset = keys(newmap);
for idx = 1:length(keyset)
if strcmp(class(newmap(keyset{idx})), 'containers.Map')
newmap(keyset{idx}) = map_deepcopy(newmap(keyset{idx}));
end
end

Regards - Marie
0 new messages