首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >根据对象的属性对对象的向量进行排序

根据对象的属性对对象的向量进行排序
EN

Stack Overflow用户
提问于 2011-03-03 06:03:37
回答 5查看 10.6K关注 0票数 10

我正在为学校做一个项目,需要整理一些数据。我得到了一个对象的向量,我必须根据对象的一个属性对对象进行排序(就地或使用索引)。有几个不同的对象和几个不同的属性可以对其进行排序。做这件事最好的方法是什么?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2011-03-03 07:08:58

有几个不同的对象和几个不同的属性可以对其进行排序。

虽然Erik发布的解决方案是正确的,但这句话让我认为,如果你实际上计划在同一个程序中以多种方式对多个类的多个公共数据成员进行排序,那么它是不切实际的,因为每个排序方法都需要自己的函数器类型。

我推荐以下抽象:

代码语言:javascript
运行
复制
#include <functional>

template<typename C, typename M, template<typename> class Pred = std::less>
struct member_comparer : std::binary_function<C, C, bool> {
    explicit member_comparer(M C::*ptr) : ptr_{ptr} { }

    bool operator ()(C const& lhs, C const& rhs) const {
        return Pred<M>{}(lhs.*ptr_, rhs.*ptr_);
    }

private:
    M C::*ptr_;
};

template<template<typename> class Pred = std::less, typename C, typename M>
member_comparer<C, M, Pred> make_member_comparer(M C::*ptr) {
    return member_comparer<C, M, Pred>{ptr};
}

用法如下所示:

代码语言:javascript
运行
复制
#include <algorithm>
#include <string>
#include <vector>

struct MyClass {
    int         i;
    std::string s;

    MyClass(int i_, std::string const& s_) : i{i_}, s{s_} { }
};

int main() {
    std::vector<MyClass> vec;
    vec.emplace_back(2, "two");
    vec.emplace_back(8, "eight");

    // sort by i, ascending
    std::sort(vec.begin(), vec.end(), make_member_comparer(&MyClass::i));
    // sort by s, ascending
    std::sort(vec.begin(), vec.end(), make_member_comparer(&MyClass::s));
    // sort by s, descending
    std::sort(vec.begin(), vec.end(), make_member_comparer<std::greater>(&MyClass::s));
}

这将适用于任何具有公共数据成员的类型,并且如果您需要以多种不同的方式对类进行排序,则可以节省大量的输入。

下面是一个使用公共成员函数而不是公共数据成员的变体:

代码语言:javascript
运行
复制
#include <functional>

template<typename C, typename M, template<typename> class Pred = std::less>
struct method_comparer : std::binary_function<C, C, bool> {
    explicit method_comparer(M (C::*ptr)() const) : ptr_{ptr} { }

    bool operator ()(C const& lhs, C const& rhs) const {
        return Pred<M>{}((lhs.*ptr_)(), (rhs.*ptr_)());
    }

private:
    M (C::*ptr_)() const;
};

template<template<typename> class Pred = std::less, typename C, typename M>
method_comparer<C, M, Pred> make_method_comparer(M (C::*ptr)() const) {
    return method_comparer<C, M, Pred>{ptr};
}

用法如下:

代码语言:javascript
运行
复制
#include <algorithm>
#include <string>
#include <vector>

class MyClass {
    int         i_;
    std::string s_;

public:
    MyClass(int i, std::string const& s) : i_{i}, s_{s} { }

    int                i() const { return i_; }
    std::string const& s() const { return s_; }
};

int main() {
    std::vector<MyClass> vec;
    vec.emplace_back(2, "two");
    vec.emplace_back(8, "eight");

    // sort by i(), ascending
    std::sort(vec.begin(), vec.end(), make_method_comparer(&MyClass::i));
    // sort by s(), ascending
    std::sort(vec.begin(), vec.end(), make_method_comparer(&MyClass::s));
    // sort by s(), descending
    std::sort(vec.begin(), vec.end(), make_method_comparer<std::greater>(&MyClass::s));
}
票数 14
EN

Stack Overflow用户

发布于 2011-03-03 06:05:53

使用std::sort和一个函数器。例如:

代码语言:javascript
运行
复制
struct SortByX
{
   bool operator() const (MyClass const & L, MyClass const & R) { return L.x < R.x; }
};

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

对于您期望的排序顺序,如果L小于R,函数器的运算符()应返回true。

票数 18
EN

Stack Overflow用户

发布于 2013-10-04 01:53:01

这是我的答案,只需使用lambda函数!它工作,它使用了更少的代码,在我看来它是优雅的!

代码语言:javascript
运行
复制
#include <algorithm>
#include <vector>
#include <string>

struct MyClass
{
    int i;
    std::string s;

    MyClass(int i_, std::string const& s_) : i(i_), s(s_) { }
};

int main()
{
    std::vector<MyClass> vec;
    vec.push_back(MyClass(2, "two"));
    vec.push_back(MyClass(8, "eight"));

    // sort by i, ascending
    std::sort(vec.begin(), vec.end(), [](MyClass a, MyClass b){ return a.i < b.i; });
    // sort by s, ascending
    std::sort(vec.begin(), vec.end(), [](MyClass a, MyClass b){ return a.s < b.s; });
    // sort by s, descending
    std::sort(vec.begin(), vec.end(), [](MyClass a, MyClass b){ return a.s > b.s; });
}
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5174115

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档