2012-03-21 89 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); 
} 
相關問題