In this article we will see how to use external Sorting Criteria i.e. Comparator in std::set.
Suppose our class is Message that contains three properties i.e.
• Member content
• Sending User Name
• Receiving User Name
Requirement:
we want to keep only single message sent by each user i.e. only one sent message is allowed per user and we can’t modify operator <.
Solution:
Frequently Asked:
Use external sorting criteria i.e. comparator
Message Class,
#include<iostream> #include<set> #include<string> class Message { public: std::string m_MsgContent; std::string m_sentBy; std::string m_recivedBy; Message(std::string sentBy, std::string recBy, std::string msg) : m_MsgContent(msg), m_sentBy(sentBy), m_recivedBy(recBy) {} friend std::ostream& operator<<(std::ostream& os, const Message& obj); }; std::ostream& operator<<(std::ostream& os, const Message& obj) { os<<obj.m_sentBy<<" :: "<<obj.m_MsgContent<<" :: "<<obj.m_recivedBy<<std::endl; return os; }
Now create a Message comparator,
class MessageUserComparator { std::string m_userName; public: MessageUserComparator(std::string userName) : m_userName(userName) {} bool operator() (const Message& msg1, const Message& msg2) const { if(msg1.m_sentBy < msg2.m_sentBy ) return true; else return false; } };
According to above implementation of comparator two Message objects are compared on the bases of all the sent user name.
[showads ad=inside_post]
Best Resources to Learn C++:
So suppose we created 4 Message objects,
Message msg1("user_1", "Hello", "user_2"); Message msg2("user_1", "Hello", "user_3"); Message msg3("user_3", "Hello", "user_1"); Message msg4("user_1", "Hello", "user_3");
Here only msg1, msg2 and msg4 are equal because according to MessageUserComparator implementation.
So, if we insert all the above objects in std::set i.e.
std::set<Message, MessageUserComparator> setOfMsgs; Message msg1("user_1", "Hello", "user_2"); Message msg2("user_1", "Hello", "user_3"); Message msg3("user_3", "Hello", "user_1"); Message msg4("user_1", "Hello", "user_3");
Then out of 4 only 2 will be inserted.
Let’s use the message comparator with std::set of messages,
int main() { Message msg1("user_1", "Hello", "user_2"); Message msg2("user_1", "Hello", "user_3"); Message msg3("user_3", "Hello", "user_1"); Message msg4("user_1", "Hello", "user_3"); // std::set that contains the messages sent by user - "user_1" std::cout<<"set that contains the messages sent by user - user_1"<<std::endl; std::set<Message, MessageUserComparator> setOfMsgs_1(MessageUserComparator("user_1")); setOfMsgs_1.insert(msg1); setOfMsgs_1.insert(msg2); setOfMsgs_1.insert(msg3); setOfMsgs_1.insert(msg4); // msg1, msg2 and msg4 are duplicates according to MessageUserComparator implementation // hence only 2 element are actually inserted in std::set // Iterate through all the elements in a set and display the value. for (std::set<Message>::iterator it=setOfMsgs_1.begin(); it!=setOfMsgs_1.end(); ++it) std::cout << *it ; return 0; }
Output:
user_1 :: user_2 :: Hello
user_3 :: user_1 :: Hello
Thanks.
I’m reading this tutorial because i want to reorder a map i made of letter frequency in a text file. but i want to order the output in descending order of frequency…which is the value…instead of the character..which is the key in my case..this doesnt help me
Hi Luis,
Yes this article will not fit as solution to your problem.
What You need is basically sorting a map by value.
Check following article,
https://thispointer.com//how-to-sort-a-map-by-value-in-c/
It will server the purpose.
Thanks,
Varun