How to use std::sort with a vector of structures and compare function?
std::sort
takes a different compare function from that used in qsort
. Instead of returning –1, 0 or 1, this function is expected to return a bool
value indicating whether the first element is less than the second.
You have two possibilites: implement operator <
for your objects; in that case, the default sort
invocation without a third argument will work; or you can rewrite your above function to accomplish the same thing.
Notice that you have to use strong typing in the arguments.
Additionally, it's good not to use a function here at all. Instead, use a function object. These benefit from inlining.
struct pkt_less {
bool operator ()(pkt const& a, pkt const& b) const {
if (a.alfa < b.alfa) return true;
if (a.alfa > b.alfa) return false;
if (a.x < b.x) return true;
if (a.x > b.x) return false;
return false;
}
};
// Usage:
sort(wektor.begin(), wektor.end(), pkt_less());
sorting a vector of structs
Use a comparison function:
bool compareByLength(const data &a, const data &b)
{
return a.word.size() < b.word.size();
}
and then use std::sort
in the header #include <algorithm>
:
std::sort(info.begin(), info.end(), compareByLength);
Sort vector of structs by a variable within the struct?
You can use std::sort with a custom comparison function:
bool is_younger(const Data& x, const Data& y) { return x.age < y.age; }
sorting:
std::sort(VectorOfData.begin(), VectorOfData.end(), is_younger);
Alternatively, you can define a custom functor (note: this is actually preferred, as it increases the likelihood of inlining, read: faster sorting)
struct is_younger_functor
{
bool operator()(const Data& x, const Data& y) const
{
return x.age < y.age;
}
};
sorting:
std::sort(VectorOfData.begin(), VectorOfData.end(), is_younger_functor());
If you want to define a strict ordering relationship for Data
, you should consider turning it into a regular type (define operators <, <=, ==, !=, >, >=).
In that case, you will not need to define this is_younger functor and can call std::sort with just the iterators.
Edit: Strictly, you only need to define operator < for std::sort, but if you define it, it is a good idea to define the rest of them.
How to sort a vector of structs based on a vector string within the vector to be sorted?
Provide a suitable comparison binary function and pass it on to std::sort
. For example
bool cmp(const sentence& lhs, const sentence & rhs)
{
return lhs.words[0] < rhs.words[0];
}
then
std::sort(allSentences.begin(), allSentences.end(), cmp);
Alternatively, in C++11 you can use a lambda anonymous function
std::sort(allSentences.begin(), allSentences.end(),
[](const sentence& lhs, const sentence & rhs) {
return lhs.words[0] < rhs.words[0];}
);
Sorting a vector of structs c++
Learning about "custom comparators" will solve your problem. Here is one of the ways to achieve the desired result. I am using cmp
as a custom comparator. Notice that it is passed while calling sort()
.
This way is useful if you need to sort on basis of something else tomorrow, say phoneNumber
. The only change you would need is adding or updating a comparator function to return c1.phoneNumber < c2.phoneNumber;
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef struct contacts
{
string name;
string nickName;
string phoneNumber;
string carrier;
string address;
//callDetails callDetails;
} contactDetails;
//sort based on name
bool cmp (const contacts& c1, const contacts& c2) {
return c1.name < c2.name;
}
void print(vector <contactDetails> proContactFile) {
for (auto s : proContactFile) {
cout << s.name << " " << s.nickName << " " << s.phoneNumber << " " << s.carrier << " " << s.address << endl;
}
}
int main()
{
vector <contactDetails> proContactFile;
proContactFile.push_back({"name1","nickName1","phone1","carrier1", "address1"});
proContactFile.push_back({ "ame1","ickName1","hone1","arrier1", "ddress1" });
proContactFile.push_back({ "me1","ckName1","one1","rrier1", "dress1" });
proContactFile.push_back({ "e1","kName1","ne1","rier1", "ress1" });
sort(proContactFile.begin(), proContactFile.end(), cmp);
print(proContactFile);
}
Sorting a vector of structs in C++
If you absolutely must use qsort
on a vector
(and you don't. And shouldn't), then you have to pass it like this:
qsort(standings.data(), standings.size(), sizeof(results), comparare);
vector::data
fetches a pointer to the array stored in the vector
. Simply passing a pointer to the vector
itself will not help.
Note that vector::data
requires C++11; use &vector[0]
if data
is not available to you.
But really, just use std::sort
:
std::sort(standings.begin(), standings.end(), [](const results &lhs, const results &rhs) {return lhs.id < rhs.id;});
Obviously the lambda requires C++11; feel free to use a namespace-declared struct for earlier C++ versions.
Related Topics
C++ Object Size with Virtual Methods
What Is the Proper Use of the Comma Operator
Why How to Not Brace Initialize a Struct Derived from Another Struct
In C++ , What's So Special About "_Move_H"
Is There a Production Ready Lock-Free Queue or Hash Implementation in C++
Qgraphicsview Zooming in and Out Under Mouse Position Using Mouse Wheel
M_Pi Works with Math.H But Not with Cmath in Visual Studio
How to Use Unique_Ptr for Pimpl
"Not Declared in This Scope" Error with Templates and Inheritance
C++, Sort One Vector Based on Another One
Parameter Pack Must Be at the End of the Parameter List... When and Why
What Is the C++ Compiler Required to Do with Ill-Formed Programs According to the Standard
Operator< Comparing Multiple Fields