Sorting a Vector of Custom Objects

Sorting a vector of custom objects

A simple example using std::sort

struct MyStruct
{
int key;
std::string stringValue;

MyStruct(int k, const std::string& s) : key(k), stringValue(s) {}
};

struct less_than_key
{
inline bool operator() (const MyStruct& struct1, const MyStruct& struct2)
{
return (struct1.key < struct2.key);
}
};

std::vector < MyStruct > vec;

vec.push_back(MyStruct(4, "test"));
vec.push_back(MyStruct(3, "a"));
vec.push_back(MyStruct(2, "is"));
vec.push_back(MyStruct(1, "this"));

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

Edit: As Kirill V. Lyadvinsky pointed out, instead of supplying a sort predicate, you can implement the operator< for MyStruct:

struct MyStruct
{
int key;
std::string stringValue;

MyStruct(int k, const std::string& s) : key(k), stringValue(s) {}

bool operator < (const MyStruct& str) const
{
return (key < str.key);
}
};

Using this method means you can simply sort the vector as follows:

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

Edit2: As Kappa suggests you can also sort the vector in the descending order by overloading a > operator and changing call of sort a bit:

struct MyStruct
{
int key;
std::string stringValue;

MyStruct(int k, const std::string& s) : key(k), stringValue(s) {}

bool operator > (const MyStruct& str) const
{
return (key > str.key);
}
};

And you should call sort as:

std::sort(vec.begin(), vec.end(),greater<MyStruct>());

Sort a vector of custom objects

Below is a example that will allow you to sort by a specified field of ItemLocation:

public void sort(final String field, List<ItemLocation> itemLocationList) {
Collections.sort(itemLocationList, new Comparator<ItemLocation>() {
@Override
public int compare(ItemLocation o1, ItemLocation o2) {
if(field.equals("icon")) {
return o1.icon.compareTo(o2.icon);
} if(field.equals("title")) {
return o1.title.compareTo(o2.title);
} else if(field.equals("message")) {
return o1.message.compareTo(o2.message);
}
.
. fill in the rest of the fields...
.
else if(field.equals("locSeen")) {
return o1.locSeen.compareTo(o2.locSeen);
}
}
});
}

Sorting a vector of custom objects with const member

Well, the way that sort is going to be implemented is that it will swap objects as needed. A class with a const member and no copy or move assignment operators is not going to be "swappable".

I would probably make the id member private and non-const. Then I'd have it accessed via a getter (but not providing a setter). Making it logically const, but the class would be copyable.

Something like this:

class A {
public:
A(int id) : id_(id) {}

bool operator<(const A &other) const {
return id_ < other.id_;
}

int id() const { return id_; }

private:
int id_;
};

sorting a vector of classes based on a variable in the class [duplicate]

If you have a vector of your class object

std::vector<MyClass> objs;

And the variable to sort by is

MyClass.value

Then you can

std::sort(objs.begin(),
objs.end(),
[](const MyClass& lhs, const MyClass& rhs)
{
return lhs.value < rhs.value;
});

c++ sorting custom objects in vector

The problem is that objects of your class Event cannot be assigned because of const double time member. Since the member is const it cannot be modified, so you cannot use sort on a container with Event objects, because sorting requires assignment.

Either remove const or rethink what you try to do. BTW you are confusing assignment operator (operator=, this is what sort requires) with equality operator (operator==`).

Sorting a Vector of Custom Objects by overloading

Since you are sorting a vector of pointers, but the operator applies to a struct, C++ ignores your operator < overload.

You can supply a custom comparer that calls your operator <, like this

std::sort(test.begin(), test.end(), [](const node* pa, const node* pb) {
return (*pb) < (*pa);
});

or code the comparison straight into the lambda, and drop the unused overload of <, like this:

std::sort(test.begin(), test.end(), [](const node* pa, const node* pb) {
return pb->frequency < pa->frequency;
});

C++ trouble sorting a vector of custom objects

std::sort and std::unique both need to compare items to do their jobs. They have somewhat different requirements though: std::unique compares for equality and std::sort compares for ordering. One obvious possibility for your case would be code on this general order:

bool operator==(Vertex const &other) const {
return num == other.num;
}

bool operator<(Vertex const &other) const {
return num < other.num;
}

[Note: these would be member functions of your Vertex class.]

It's possible to implement the required functionality in other ways, especially if (for example) you might want to sort objects based on one field sometimes, and by another field at other times (e.g., sort by number and sort by name, in the case of your Vertex class).

You can do that by passing a third parameter to sort and/or unique to tell it what to use to do the comparison. At least in current C++, if I'm going to do this, I generally use a lambda expression to specify the comparison:

std::sort(v.begin(), v.end(),
[](Vertex const &a, Vertex const &b) { return a.name < b.name; });

This puts the comparison code right next to the sort, so it's easy to see how you're doing the sorting. You can use a separate function or function object instead, but doing so means you need to be careful with the name to ensure it describes the sort order:

struct by_name {
bool operator()(Vertex const &a, Vertex const &b) const {
return a.name < b.name;
}
};

// ...
std:sort(v.begin(), v.end(), by_name());


Related Topics



Leave a reply



Submit