Remove if, all but one instance

Is it possible implement a "remove_if" statement so that it can delete duplicates in a map, but leave one instance of the element? If I have a multimap of names and one name was listed twice (x=2) it would erase one of the duplicates (so that x=1).
Last edited on
Hi,

Does this algorithm suit your needs? Will need to sort the container first.

http://www.cplusplus.com/reference/algorithm/unique/


If you are not allowed to use this algorithm, then consider sorting first, Iterate through the container, delete if a duplicate.

Hope all goes well :+)
Does the algorithm "unique_copy" work with a map? Because that's closer to what I'm trying to do.

The only problem with unique copy are that the parameters are so specific, that I can't get it to work.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <string>
#include <map>
#include <algorithm>
#include <set>

std::multimap< std::string, int > remove_duplicates( std::multimap< std::string, int > mmap )
{
    std::set< std::pair< std::string, int > > unique_pairs( mmap.begin(), mmap.end() ) ;
    return { unique_pairs.begin(), unique_pairs.end() } ;
}

int main()
{
    std::multimap< std::string, int > my_map { { "abcd", 1 }, { "abcd", 2 }, { "abcd", 3 }, { "abcd", 1 },
                                               { "efgh", 1 }, { "efgh", 2 }, { "efgh", 1 }, { "efgh", 2 } } ;
    for( const auto& pair : my_map ) std::cout << pair.first << ' ' << pair.second << '\n' ;

    std::cout << "===== after removing duplicate entries =======\n" ;

    my_map = remove_duplicates(my_map) ;
    for( const auto& pair : my_map ) std::cout << pair.first << ' ' << pair.second << '\n' ;
}

http://coliru.stacked-crooked.com/a/9329d51d917c64ec
Many different ways...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
 // http://ideone.com/Ir7I8e
#include <algorithm>
#include <iostream>
#include <iterator>
#include <map>
#include <string>
#include <tuple>

using container_type = std::multimap<std::string, int>;

std::multimap<std::string, int> original_table =
{
    {"a", 1},
    {"c", 2},
    {"b", 3},
    {"b", 4},
    {"a", 5},
    {"b", 6}
};

void unique(container_type& container)
{
    for (auto iter = begin(container); iter != end(container); ++iter)
    {
        auto last = container.upper_bound(iter->first);
        container.erase(next(iter), last);
    }
}

template <typename container_t>
void print_associative(const container_t& c)
{
    for (auto& item : c)
        std::cout << item.first << ": " << item.second << '\n';
}

int main()
{
    container_type table(original_table);

    std::cout << "Before:\n";
    print_associative(table);


    unique(table);
    std::cout << "\nAfter:\n";
    print_associative(table);


    using key_type = container_type::key_type;
    using mapped_type = container_type::mapped_type;
    std::map<key_type, mapped_type> m(begin(original_table), end(original_table));

    std::cout << "\nMap:\n";
    print_associative(m);


    using value_type = container_type::value_type;
    auto value_equal = [](value_type& a, value_type&b) { return a.first == b.first; };

    container_type unique_copy_result;
    std::unique_copy(begin(original_table), end(original_table), 
                     std::inserter(unique_copy_result, begin(unique_copy_result)),
                     value_equal);

    std::cout << "\nUnique_copy:\n";
    print_associative(unique_copy_result);
}


[edit: Note that this is different functionality than that supplied by JLBorge. Likely his is more in line with what you want, but all of these methods (except the map conversion) could be modified to provide equivalent functionality if you so desired. Your original post wasn't entirely clear on your end goal. Remove dupicate keys or remove duplicate key/values combinations? The code above removes duplicate keys, by arbitrarily keeping the first encountered. The code supplied by JLBorge removes duplicate key/value combinations.]
Last edited on
Topic archived. No new replies allowed.