Re: How to avoid CMapStringToPtr sorting ?
Abin wrote:
ok here goes my doubt. Please see the code below.
CMapStringToOb m_myMap;
m_myMap.SetAt("CCC",0);
m_myMap.SetAt("ZEE",0);
m_myMap.SetAt("ABB",0);
POSITION pPos = m_myMap.GetStartPosition();
CString strName;
CObject *pObj;
while (pPos != NULL)
{
m_myMap.GetNextAssoc(pPos, strName, pObj);
AfxMessageBox(strName);
}
<<<<<<<<<
When i iterate the keys i get "ZEE", "ABB" followed by "CCC".
Is there any way to retrieve the keys in same order of insertion.
Hi Abin,
The MS Doc says: 'You might think that this iteration is sequential by
key value; it is not. The sequence of retrieved elements is indeterminate.'
So no, by using the container as exposed.
Do you need to use a map? You can look up objects in a sequential
container. The only reason for a map is lookup time. If you know your
lists will be short and/or lookups are not intense, just use CArray.
Correct me if I'm wrong, but I think you grabbed CMapStringToOb to avoid
a template class. But if you are going to use containers effectively,
you will have to at some point.
So, if it your goal to have speedy random access to the elements _and_
control the order, you will have to go with what Giovanni or David
posted. But I doubt you do. And if you don't but may in the future,
there is a methodical way to plan for it.
There are two kind of basic containers. Associative, the one you have
now, and sequential. Simplest example of sequential with two objects per
item. You can just copy and paste this to see it work:
//
struct MyObj
{
CString name;
long number;
};
//Use typedefs, it will pay off later:
typedef std::vector< MyObj > MyContainer;
typedef std::vector< MyObj >::iterator MyCIt;
//Now code:
void test( )
{
MyContainer container;
MyObj obj;
obj.name= _T("AAA");
obj.number= 123;
container.push_back( obj );
obj.name= _T("ZZZ");
obj.number= 345;
container.push_back( obj );
obj.name= _T("MMM");
obj.number= 456;
container.push_back( obj );
//display the container
for( MyCIt it= container.begin( ); it != container.end( ); ++it )
TRACE( "%s %d\n", it->name, it->number );
//show the second item
TRACE( "*two* %s %d\n", container[1].name, container[1].number );
}
Note that you should use TRACE instead of AfxMessageBox for this stuff.
This addresses the only goal you seem to have for now. You can do the
same thing with CArray which is just the MFC version of std::vector.
Best, Dan.