how to remove duplicates of a vector of structures c++

Viewed 787

I have the vector movements

 vector<posToMove> movements;

posToMove is a structure:

struct posToMove
{
    int fromX;
    int fromY;
    int toX;
    int toY;
};

I want to remove the duplicates that are in movements, how do I do that?

1 Answers

The simplest way is to use :

movements.erase(std::unique(movements.begin(), movements.end()), movements.end());

But std::unique only removes consecutive duplicated elements, so you need to sort the std::vector first, by overloading < and == operator:

struct posToMove
{
    int fromX;
    int fromY;
    int toX;
    int toY;

    bool operator < (const posToMove& other) const
    {
        //declare how 2 variable of type posToMove should be compared with <
        return std::make_tuple(fromX, fromY, toX, toY) < std::make_tuple(other.fromX, other.fromY, other.toX, other.toY);
    }

    bool operator == (const posToMove& other) const
    {
        //declare how 2 variable of type posToMove should be compared with ==
        return std::make_tuple(fromX, fromY, toX, toY) == std::make_tuple(other.fromX, other.fromY, other.toX, other.toY);
    }
};

I declared < and == operator with make_tuple(), but you can replace that with your choice of comparing as well.

Code :

#include <iostream>
#include <vector>
#include <tuple>
#include <algorithm>
struct posToMove
{
    int fromX;
    int fromY;
    int toX;
    int toY;

    bool operator < (const posToMove& other) const
    {
        //declare how 2 variable of type posToMove should be compared with <
        return std::make_tuple(fromX, fromY, toX, toY) < std::make_tuple(other.fromX, other.fromY, other.toX, other.toY);
    }

    bool operator == (const posToMove& other) const
    {
        //declare how 2 variable of type posToMove should be compared with ==
        return std::make_tuple(fromX, fromY, toX, toY) == std::make_tuple(other.fromX, other.fromY, other.toX, other.toY);
    }
};

std::vector<posToMove>movements;

int main()
{
    movements.push_back({0,1,0,0});
    movements.push_back({1,2,5,7});
    movements.push_back({3,9,9,6});
    movements.push_back({0,1,0,0});
    movements.push_back({4,1,8,0});
    movements.push_back({1,2,5,7});

    std::sort(movements.begin(), movements.end());

    std::cout << "After sort : \n";
    for (auto x : movements)
    {
        std::cout << x.fromX << " " << x.fromY << " " << x.toX << " " << x.toY << "\n";
    }
    std::cout << "\n";

    movements.erase(std::unique(movements.begin(), movements.end()), movements.end());

    std::cout << "After removing : \n";
    for (auto x : movements)
    {
        std::cout << x.fromX << " " << x.fromY << " " << x.toX << " " << x.toY << "\n";
    }
}

Result:

After sort :
0 1 0 0
0 1 0 0
1 2 5 7
1 2 5 7
3 9 9 6
4 1 8 0

After removing :
0 1 0 0
1 2 5 7
3 9 9 6
4 1 8 0

Related : Remove duplicates in vector of structure c++

Documentations:

Related