-2

If anyone can help I would be very grateful. How do i sort this vector:

vector<Person*>person

by this criterium:

Surname

I have already tried it using set but it removes object if there is more than 2 objects with same Surname

there are lot of string variables, and I need to sort it by

Surname

and then if surnames are the same, then I need to sort them by

Name

and also it sorts by hexadecimal value of that pointer... EDIT: More code as you ask:

for (pChild = pRoot->FirstChildElement("Member"); pChild != NULL; pChild = pChild->NextSiblingElement())
    {
        string Surname = pChild->Attribute("surname");
        string Name = pChild->Attribute("name");
        string DateOfBirth = pChild->Attribute("dateofbirth");
        person.push_back(new Person(Surname, Name, DateOfBirth));
    }
  • 2
    Please make a [minimal-reproducible-example](https://stackoverflow.com/help/minimal-reproducible-example) – cigien May 29 '20 at 16:39
  • If set sorts correctly you can use multy_set – Olexy May 29 '20 at 16:40
  • Set does sort it correctly, but only hexadecimal values, but not the string variable... –  May 29 '20 at 16:41
  • 1
    You can use a comparator. see this: https://stackoverflow.com/questions/1380463/sorting-a-vector-of-custom-objects – Tanya May 29 '20 at 16:42
  • @Tanya I think i have tried this example before, but it didnt seem to work with pointer... –  May 29 '20 at 16:43
  • set need overloaded comparision operators, i can not help more without example – Olexy May 29 '20 at 16:47
  • 2
    @NikolaStjepanović Create a comparator function that takes pointers to objects and returns results based on the contents of the pointed-to objects. – Zan Lynx May 29 '20 at 16:48
  • Custom comparators or lambdas can help you achieve what you want, using `std::sort(it_begin, it_end, compare )` from STL algorithms – rekkalmd May 29 '20 at 16:54
  • Have you considered not storing a pointer? `vector`, and library containers in general, do their best work when they directly contain, rather than pointer to, objects. – user4581301 May 29 '20 at 16:56
  • Then TinyXML2 doesnt seem to work –  May 29 '20 at 16:57

4 Answers4

2

Without you showing more of your code, it is hard to help you, but I would look at the documentation for std::sort() as you can create custom operators to sort your vector.

arc-menace
  • 435
  • 6
  • 19
  • I have vector of objects, but there is pointer on object. So what I need to sort is that whole vector, so all of the members of that vector sort are by this variable: m_sSurname (I have stored string and int variables into object, and then that object is stored in that vector) –  May 29 '20 at 16:46
  • 1
    @NikolaStjepanović did you read the documentation? You're simply repeating what you've already said in your question. Pay special attention to the third parameter `comp`. – alter_igel May 29 '20 at 16:50
  • Added more example, which info i store into vector. –  May 29 '20 at 16:51
  • This answer is exactly what is posted below only in word form. – Bayleef May 29 '20 at 17:09
  • @BaileyKocin to be fair, I had very little information to go off of when the question was first posted. – arc-menace May 29 '20 at 17:10
  • Its not a bad thing. I think the op just wanted the answer fed to them. – Bayleef May 29 '20 at 17:11
0

You can use a comparator like this:

// Simple class
class Person {
    public:
     string name;
    Person(string name) {
      this->name = name;
    }
};

// create a comparator like this with two objects as parameters.
bool comparator(Person* a, Person *b) {
  return a->name > b->name;
}

int main() {
  vector<Person* > v;
  v.push_back(new Person("ajay"));
  v.push_back(new Person("tanya"));

  // pass the comparator created into sort function.
  sort(v.begin(), v.end(),comparator);

  // printing output to check
  for(int i=0;i<v.size();i++) {
    cout<<v[i]->name<<endl;
  }
}
Rishabh Agarwal
  • 1,988
  • 1
  • 16
  • 33
Tanya
  • 88
  • 8
  • 3
    Please dont include bits/std++.h without need. The op uses 3 headers. They shouldn't include all those precompiled ones. – Bayleef May 29 '20 at 17:13
0

Here's a complete example

#include <vector>
#include <iostream>
#include <algorithm>

class Person
{
public:
    std::string s1, s2, s3;

    Person(std::string S1, std::string S2, std::string S3) : s1(S1), s2(S2), s3(S3) {}
};

struct less_than_key
{
    inline bool operator() (const Person* const p1, const Person* const p2)
    {
        if (p1->s1 < p2->s1)
            return true;
        else if (p1->s1 == p2->s1 && p1->s2 < p2->s2)
            return true;

        return false;
    }
};

int main()
{
    std::vector<Person*> persons{ new Person("C", "D", "E"), new Person("C", "C", "D"),
                                  new Person("B", "C", "D"), new Person("B", "C", "E")};

    std::sort(persons.begin(), persons.end(), less_than_key());

    for (auto person : persons)
    {
        std::cout << person->s1 << ' ' << person->s2 << std::endl;
    }

    return 0;
}
Uri Raz
  • 435
  • 1
  • 3
  • 15
0

I had a bit of fun doing it with std::set. There are a couple of examples of comparators. One function and one "functor."

#include <iostream>
#include <set>
#include <string>

struct Person {
  uint64_t id;
  std::string name;
  std::string family_name;

  bool operator<(const Person &other) const {
    if (family_name == other.family_name) {
      if (name == other.name) {
        return id < other.id;
      } else {
        return name < other.name;
      }
    } else {
      return family_name < other.family_name;
    }
  }
};

std::ostream &operator<<(std::ostream &os, const Person &x) {
  return os << '{' << x.id << ", " << x.name << ", " << x.family_name << '}';
}

bool person_ptr_less(const Person *a, const Person *b) { return *a < *b; }

class PersonPtrComparator {
public:
  bool operator()(const Person *a, const Person *b) const { return *a < *b; }
};

int main() {
  std::set<Person *, bool (*)(const Person *, const Person *)> people(
      person_ptr_less);
  people.emplace(new Person{1, "Joe", "Smith"});
  people.emplace(new Person{2, "Joe", "Blow"});
  people.emplace(new Person{3, "Joa", "Smith"});
  people.emplace(new Person{4, "Joe", "Smith"});

  std::set<Person *, PersonPtrComparator> people_2(people.begin(),
                                                   people.end());

  for (const auto &x : people) {
    std::cout << *x << '\n';
  }
  std::cout << "---\n";
  for (const auto &x : people_2) {
    std::cout << *x << '\n';
  }
  return 0;
}
Zan Lynx
  • 53,022
  • 10
  • 79
  • 131
  • Thank you, I tried this code in my example, it worked aswell as last answer too. –  May 30 '20 at 06:22