Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nested Dictionary/Array in C++

Everybody, I am a Python/C# guy and I am trying to learn C++. In Python I used to do things like:
myRoutes = {0:[1,2,3], 1:[[1,2],[3,4]], 2:[[1,2,3],[[1,2,3],[1,2,3]],[4]]}

Basically when you have arrays of variable length and you don't want to wast a 2D matrix for them, nesting arrays into a dictionary to keep track of them is a good option.

In C++ I tried std::map<int, std:map<int, std:map<int, int> > > and it works but I feel there got to bo a better way to do this.

I prefer to stick to the standard libraries but popular libraries like boost are also acceptable for me.

I appreciate your help,
Ali

like image 1000
Ali Avatar asked Mar 03 '11 00:03

Ali


2 Answers

It looks like part of the question is: 'How do I store heterogeneous data in a container?' There are several different approaches:

1) Use a ready-made class of array types that abstracts away the exact details (i.e., dimensionality). Example: Boost Basic Linear Algebra

2) Make an explicit list of element types, using Boost.variant

   #import "boost/variant.hpp"

   typedef boost::variant< ArrayTypeA, ArrayTypeB > mapelement;
   typedef std::map<int, mapelement> mappingtype;

Building a visitor for variant type is a bit involved (it involves writing a subclass of boost::static_visitor<desired_return_type> with a single operator() overload for each type in your variant). On the plus side, visitors are statically type checked to ens ure that they implement the exact right set of handlers.

3) Use a wrapper type, like Boost.Any to wrap the different types of interest.


Overall, I think the first option (using a specialized array class) is probably the most reliable. I have also used variants heavily in recent code, and although the compile errors are long, once one gets used to those, it is great to have compile time checking, which I prefer strongly over Python's "run and find out you were wrong later" paradigm.

like image 192
phooji Avatar answered Sep 28 '22 22:09

phooji


Many of us share the pain you're experiencing right now but there are solutions to them. One of those solutions is the Boost library (it's like the 2nd standard library of C++.) There's quite a few collection libraries. In your case I'd use Boost::Multi-Dimentional Arrays.

Looks like this:

boost::multi_array<double,3> myArray(boost::extents[2][2][2]);

Which creates a 2x2x2 array. The first type in the template parameters "double" specifies what type the array will hold and the second "3" the dimension count of the array. You then use the "extents" to impart the actual size of each of the dimensions. Quite easy to use and syntatically clear in its intent.

Now, if you're dealing with something in Python like foo = {0:[1,2,3], 1:[3,4,5]} what you're really looking for is a multimap. This is part of the standard library and is essentially a Red-Black tree, indexed by key but with a List for the value.

like image 35
wheaties Avatar answered Sep 29 '22 00:09

wheaties