Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Resorting a map (copying a map to another with different Compare)

Reply
Thread Tools

Resorting a map (copying a map to another with different Compare)

 
 
nw
Guest
Posts: n/a
 
      03-11-2010
Hi,

I'd like to be able to re-sort a map (a curious aspiration perhaps). I
think basically what I'd like to do is copy one map into another that
uses a different Compare function. I was wondering if there was an
easy way of doing this in general. Or what strategy I could use to do
it?

I've tried something like this:

template<class map1_type,class map2_type>
void copy_map(map1_type &m1,map2_type &m2,int depth) {

if(depth > 0) {
map1_type::const_iterator i = m1.begin();
for(;i != m1.end();++i) {
copy_map(i,m2[i->first],depth-1);
}
} else {
map1_type::const_iterator i = m1.begin();
for(;i != m1.end();++i) {
m2[i->first] = m1[i->first];
}
}
}

But this fails to even compile. Does anyone have any ideas here?
 
Reply With Quote
 
 
 
 
Michael Oswald
Guest
Posts: n/a
 
      03-11-2010
Am 11.03.2010 15:12, schrieb nw:
> Hi,
>
> I'd like to be able to re-sort a map (a curious aspiration perhaps). I
> think basically what I'd like to do is copy one map into another that
> uses a different Compare function. I was wondering if there was an
> easy way of doing this in general. Or what strategy I could use to do
> it?


Maybe boost::multi_index? At least you could avoid the copying.

lg,
Michael



 
Reply With Quote
 
 
 
 
nw
Guest
Posts: n/a
 
      03-11-2010
On Mar 11, 2:31*pm, Pete Becker <(E-Mail Removed)> wrote:
> nw wrote:
> > Hi,

>
> > I'd like to be able to re-sort a map (a curious aspiration perhaps). I
> > think basically what I'd like to do is copy one map into another that
> > uses a different Compare function. I was wondering if there was an
> > easy way of doing this in general. Or what strategy I could use to do
> > it?

>
> > I've tried something like this:

>
> > template<class map1_type,class map2_type>
> > void copy_map(map1_type &m1,map2_type &m2,int depth) {

>
> > * if(depth > 0) {
> > * * map1_type::const_iterator i = m1.begin();
> > * * for(;i != m1.end();++i) {
> > * * * copy_map(i,m2[i->first],depth-1);
> > * * }
> > * } else {
> > * * map1_type::const_iterator i = m1.begin();
> > * * for(;i != m1.end();++i) {
> > * * * m2[i->first] = m1[i->first];
> > * * }
> > * }
> > }

>
> > But this fails to even compile. Does anyone have any ideas here?

>
> In general, you can copy one map into another like this:
>
> * * * * map2_type m2(m1.begin(), m1.end());
>
> --
> * *Pete
> Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of
> "The Standard C++ Library Extensions: a Tutorial and Reference"
> (www.petebecker.com/tr1book)


So I think the problem is that in general I'm trying to do this with
maps containing maps e.g.:

#include <map>
#include <iostream>

using namespace std;

class numstr_compare {

public:
inline bool operator()(const string &k1,const string &k2) const {
std::cout << "numstr compare" << std::endl;

for(size_t n=0;n<k1.size();n++) { if(!(((k1[n] >= '0') && (k1[n]
<= '9')) || k1[n] == '.')) {return k1 < k2; std::cout << "strcomp1" <<
std::endl;} }
std::cout << "str: " << k1 << std::endl;

for(size_t n=0;n<k2.size();n++) { if(!(((k2[n] >= '0') && (k2[n]
<= '9')) || k2[n] == '.')) {return k1 < k2; std::cout << "strcomp2" <<
std::endl;} }
std::cout <<" str: " << k2 << std::endl;

if(k1.size() == 0) {return k1 < k2;}
if(k2.size() == 0) {return k1 < k2;}

float k1_double = atof(k1.c_str());
float k2_double = atof(k2.c_str());
return k1_double < k2_double;

}
};


int main() {

map<string,map<string,string> > m1;

m1["stuff"] = map<string,string>();
m1["astuff"] = map<string,string>();
m1["321"] = map<string,string>();
m1["432"] = map<string,string>();
m1["12323"] = map<string,string>();
m1["123"] = map<string,string>();
m1["1"] = map<string,string>();

map<string,map<string,numstr_compare>,numstr_compa re>
m2(m1.begin(),m1.end());
}

Is there any neat solution here?
 
Reply With Quote
 
nw
Guest
Posts: n/a
 
      03-11-2010
So to clarify what I'm after is something that does this, but is
generic to different depths and map types:

#include <map>
#include <iostream>

using namespace std;

class more {

public:
inline bool operator()(const string &k1,const string &k2) const {
return k1 > k2;
}
};


void copy_map(map<string,map<string,string> > &m1,
map<string,map<string,string,more>,more> &m2) {

map<string,map<string,string> >::iterator i = m1.begin();

for(;i != m1.end();++i) {
map<string,string>::iterator i2 = (*i).second.begin();
for(;i2 != (*i).second.end();++i2) {
m2[(*i).first][(*i2).first] = (*i2).second;
}
}
}

int main() {

map<string,map<string,string> > m1;
map<string,map<string,string,more>,more> m2;

map<string,string> m3 = map<string,string>();
m3["1thing"] = "3343";
m3["2thing"] = "943";
m3["3thing"] = "23343";


m1["stuff"] = m3;
m1["astuff"] = m3;
m1["321"] = m3;
m1["432"] = m3;
m1["12323"] = m3;
m1["123"] = m3;
m1["1"] = m3;

copy_map(m1,m2);

map<string,map<string,string,more>,more>::iterator i = m2.begin();
for(;i != m2.end();++i) {
map<string,string,more>::iterator i2 = (*i).second.begin();
for(;i2 != (*i).second.end();++i2) {
std::cout << i->first << " " << i2->first << " val: " << m2[i-
>first][i2->first] << std::endl;

}
}
}
 
Reply With Quote
 
Pavel
Guest
Posts: n/a
 
      03-12-2010
nw wrote:
> Hi,
>
> I'd like to be able to re-sort a map (a curious aspiration perhaps). I
> think basically what I'd like to do is copy one map into another that
> uses a different Compare function. I was wondering if there was an
> easy way of doing this in general. Or what strategy I could use to do
> it?
>
> I've tried something like this:
>
> template<class map1_type,class map2_type>
> void copy_map(map1_type&m1,map2_type&m2,int depth) {
>
> if(depth> 0) {
> map1_type::const_iterator i = m1.begin();
> for(;i != m1.end();++i) {
> copy_map(i,m2[i->first],depth-1);
> }
> } else {
> map1_type::const_iterator i = m1.begin();
> for(;i != m1.end();++i) {
> m2[i->first] = m1[i->first];
> }
> }
> }
>
> But this fails to even compile. Does anyone have any ideas here?

The issue is that you "depth" is not a template (compile-time) but a
function (run-time) parameter. Thus, the recursive instantiation of a
template function does not have a stop condition.. The below seems to
work (hopefully this is what you meant to do):

-----------cut here---------
#include <functional>
#include <iostream>
#include <map>
using namespace std;

template <class M1, class M2, unsigned depth>
struct MapCopier {
static M2 Copy(const M1 &src) {
M2 dst;
for (typename M1::const_iterator i1 = src.begin(); i1 != src.end();
++i1) {
typedef typename M1::mapped_type M1Next;
typedef typename M2::mapped_type M2Next;
dst[i1->first] = MapCopier<M1Next, M2Next, depth - 1>
::Copy(i1->second);
}
return dst;
}
};

template <class M1, class M2>
struct MapCopier<M1, M2, 1> {
static M2 Copy(const M1 &src) {
M2 dst(src.begin(), src.end());
return dst;
}
};

struct RevComp : public binary_function<int, int, bool>
{ bool operator()(int x, int y) const { return x > y; } };

typedef map<int, map<int, int> > IM1;
typedef map<int, map<int, int, RevComp>, RevComp> IM2;


int main() {
IM1 m1;
m1[0][0] = 7;
m1[0][1] = 8;
m1[1][0] = 9;
m1[1][1] = 10;
IM2 m2 = MapCopier<IM1, IM2, 2>::Copy(m1);
for (IM2::iterator i = m2.begin(); i != m2.end(); ++i)
for (IM2::value_type::second_type::iterator j = i->second.begin();
j != i->second.end(); ++j)
cout << "m2[" << i->first << "][" << j->first << "]=" << j->second
<< '\n';
return 0;
}
-----------cut here---------

Hope this helps,
Pavel
 
Reply With Quote
 
Permostat
Guest
Posts: n/a
 
      03-12-2010
On Mar 11, 8:12*am, nw <(E-Mail Removed)> wrote:
> Hi,
>
> I'd like to be able to re-sort a map (a curious aspiration perhaps). I
> think basically what I'd like to do is copy one map into another that
> uses a different Compare function. I was wondering if there was an
> easy way of doing this in general. Or what strategy I could use to do
> it?
>
> I've tried something like this:
>
> template<class map1_type,class map2_type>
> void copy_map(map1_type &m1,map2_type &m2,int depth) {
>
> * if(depth > 0) {
> * * map1_type::const_iterator i = m1.begin();
> * * for(;i != m1.end();++i) {
> * * * copy_map(i,m2[i->first],depth-1);
> * * }
> * } else {
> * * map1_type::const_iterator i = m1.begin();
> * * for(;i != m1.end();++i) {
> * * * m2[i->first] = m1[i->first];
> * * }
> * }
>
> }
>
> But this fails to even compile. Does anyone have any ideas here?


Blast it with ****.

sperm-
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
how to put the content of one hash map to another hash map navS C++ 3 05-09-2008 12:52 PM
Resorting a dataset =?Utf-8?B?QXJuZQ==?= ASP .Net 2 11-15-2005 09:19 PM
resorting the newsgroups in the Folders panel in Thunderbird? Larry__Weiss Firefox 1 01-29-2005 01:38 AM
sorting and resorting hash Andrea Spitaleri Perl Misc 7 06-04-2004 09:17 AM
Different responses from different systems Tigerhillside Perl 3 02-23-2004 01:56 AM



Advertisments