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

Discussion in 'C++' started by nw, Mar 11, 2010.

  1. nw

    nw Guest

    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?
     
    nw, Mar 11, 2010
    #1
    1. Advertising

  2. 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
     
    Michael Oswald, Mar 11, 2010
    #2
    1. Advertising

  3. nw

    nw Guest

    On Mar 11, 2:31 pm, Pete Becker <> 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_compare>
    m2(m1.begin(),m1.end());
    }

    Is there any neat solution here?
     
    nw, Mar 11, 2010
    #3
  4. nw

    nw Guest

    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;

    }
    }
    }
     
    nw, Mar 11, 2010
    #4
  5. nw

    Pavel Guest

    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
     
    Pavel, Mar 12, 2010
    #5
  6. nw

    Permostat Guest

    On Mar 11, 8:12 am, 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?


    Blast it with piss.

    sperm-
     
    Permostat, Mar 12, 2010
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. =?Utf-8?B?QXJuZQ==?=

    Resorting a dataset

    =?Utf-8?B?QXJuZQ==?=, Nov 15, 2005, in forum: ASP .Net
    Replies:
    2
    Views:
    5,782
    =?Utf-8?B?UGhpbGxpcCBXaWxsaWFtcw==?=
    Nov 15, 2005
  2. Xavier Noria

    Copying structures of different type

    Xavier Noria, Feb 18, 2004, in forum: C Programming
    Replies:
    10
    Views:
    611
    CBFalconer
    Feb 19, 2004
  3. Replies:
    1
    Views:
    340
    John Harrison
    Feb 21, 2007
  4. navS
    Replies:
    3
    Views:
    542
    Ismo Salonen
    May 9, 2008
  5. Andrea Spitaleri

    sorting and resorting hash

    Andrea Spitaleri, Jun 2, 2004, in forum: Perl Misc
    Replies:
    7
    Views:
    146
    Andrea Spitaleri
    Jun 4, 2004
Loading...

Share This Page