2012-03-21 52 views

回答

1

Boost.Multi-index。不过,您需要提前指定要为其建立索引的所有列。

如果您在order by列中没有SQL索引,那么它只会执行线性扫描并即时创建排序结果集 - 如果您想要订购,您总是可以在C++中执行相同的操作通过一些专栏,你没有提前索引。

+0

是的,没有索引会做线性扫描这很好SQL命令。我正在寻找灵活性,以不可预知的方式进行排序,即使它可能很慢 – user841550 2012-03-21 14:48:28

2

好吧,你将不得不做一些腿部工作。

Consder作出结构或元组举行行:

struct row{ 
    unsigned rank; 
    std::string city; 
    double area; 
    //so on 
}; 

在填充载体或其它包含你行。

std::vector<row> rows; 

要使用std::sort排序使用自定义比较功能,你看看某些值。

std::sort(rows.begin(), rows.end(), [](const row& r1, const row& r2)->bool{ 
    return r1.area < r2.area; 
}); //sort by area 

这可能是由于其载体的载体和比较功能可以捕捉varaible从它的环境进行通用:看到我的其他答案

0

我会做结构的载体,每一个结构模型1该表的“行”。你可以用不同的成员使用std :: sort对它进行排序,并使用排序函数来比较你想排序的成员。

+0

是的,111111说的。 – rchilton 2012-03-21 14:30:10

0

我虽然我会发布一个通用的答案分别

考虑:

typedef std::vector<std::string> row; 
std::vector<row > table; 

填充每个内部向量,就好像它是一个行,只要确保它们都具有相同数目的元素。

然后制造出能指定的行

bool compare_index(std::size_t i, const row& v1, const row& v2) 
{ 
    return v1.at(i) < v2.at(i); 
} 

现在经营比较功能可以排序像这样

std::size_t column=2; //or which ever column 
std::sort(table.begin(), table.end(), 
      std::bind(&compare_index, col, 
       std::placeholders::_1, 
       std::placeholders::_2)); 
+0

我喜欢这个问题是你仅限于存储std :: strings。示例表中的列可以是整数或浮点数 – user841550 2012-03-21 14:44:04

+0

这是真的,但如果您希望它动态化,那么您将不得不做出更复杂的设计。使用某种多态占位符,如'boost :: variant'。但这是一个单独的问题。 (或者使用继承或类似的方式编写你自己的代码)你可以在编译时使用std :: tuple而不是struct来使其变为可变的。 – 111111 2012-03-21 14:49:50

1

确定,因此基于以下假设:

  • 你想按名称选择排序栏
  • 哟ü要存储的东西像一个struct每行(使用变量类型在这里给你买一个有限的,但你可以去元组/类型串线)

你需要:

  • 某种方式列符合实际列
  • 某处挂特定类型的分类代码

鉴于输入&输出类型(分别为未排序的容器和已排序的容器)是相同的,您可以使用运行时多态性和模板的组合来完成此操作。

这里是一个速写:

#include <vector> 
#include <set> 
#include <map> 
#include <memory> 
#include <iterator> 
#include <algorithm> 

template <typename Row> class Table 
{ 
    std::vector<Row*> rows; 

    class AbstractSorter 
    { 
    protected: 
     // this doesn't have to go in AbstractSorter, 
     // but it's only used from the derived classes 
     template <typename Comp> static 
     std::vector<Row*> sort(std::vector<Row*> const &in, Comp comp) 
     { 
      std::vector<Row*> out; 
      out.reserve(in.size()); 
      // or copy and sort in place, for example 
      std::multiset<Row*, Comp> sorted(comp); 
      std::copy(in.begin(), in.end(), std::inserter(sorted, sorted.end())); 
      std::copy(sorted.begin(), sorted.end(), std::back_inserter(out)); 

      return out; 
     } 

    public: 
     virtual ~AbstractSorter() {} 
     virtual std::vector<Row*> sort(std::vector<Row*> const &) const = 0; 
    }; 

    typedef std::unique_ptr<AbstractSorter> SortPtr; 
    typedef std::map<std::string, SortPtr> SortMap; 
    static SortMap sorters; 

    template <typename ColType> 
    class ConcreteSorter: public AbstractSorter 
    { 
     ColType Row::*col; 

    public: 
     ConcreteSorter(ColType Row::*member) : col(member) {} 
     virtual std::vector<Row*> sort(std::vector<Row*> const &in) const 
     { 
      // assuming you have C++11 lambdas, otherwise you'll need to 
      // write a comparator too 
      return AbstractSorter::sort(
       in, 
       [&col](Row *a, Row *b){ return (a->*col) < (b->*col); } 
       ); 
     } 
    }; 

public: 
    template <typename ColType> 
    static void bindSortableColumn(char const *name, ColType Row::*member) 
    { 
     sorters.insert(typename SortMap::value_type(
       std::string(name), 
       SortPtr(new ConcreteSorter<ColType>(member)) 
       )); 
    } 

    // error handling left as an exercise for the reader 
    std::vector<Row*> sortBy(std::string const &name) const 
    { 
     return sorters[name]->sort(rows); 
    } 
}; 

#define SORTABLE_COLUMN(ROW, COL) \ 
    Table<ROW>::bindSortableColumn(#COL, &ROW::COL); 

template <typename Row> typename Table<Row>::SortMap Table<Row>::sorters; 

// now to define your own row type  
struct MyRow 
{ 
    int id; 
    std::string name; 
    double salary; 
}; 

// and the tedious bit: setting up the sorter objects for your columns 
// (you could automate this further by using a tuple instead of a regular 
// struct for MyRow) 
void init_columns() 
{ 
    SORTABLE_COLUMN(MyRow, id); 
    SORTABLE_COLUMN(MyRow, name); 
    SORTABLE_COLUMN(MyRow, salary); 
} 
相关问题