是否存在结构组合(STL,Boost等)的数据结构,允许我对内存中的数据进行排序,就像在此表中所做的那样http://en.wikipedia.org/wiki/List_of_cities_proper_by_population
我想要一个可以处理任意数量和列名称的通用解决方案。基本相似
使用sql的order by clause
答案 0 :(得分: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
这可以通过使用向量向量来实现通用,并且比较函数可以从其环境中捕获变量:请参阅我的其他答案
答案 1 :(得分:1)
有Boost.Multi-index。但是,您需要提前指定要为其构建索引的所有列。
如果你order by
一个没有SQL索引的列,它只会进行线性扫描并动态构建一个排序结果集 - 你可以在C ++中做同样的事情想要通过某些专栏订购,而不是事先索引。
答案 2 :(得分: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);
}
答案 3 :(得分:0)
我会创建一个结构的向量,每个结构模型该表的1“行”。您可以使用std :: sort和使用排序函数对不同成员进行排序,该排序函数只比较您要排序的成员。
答案 4 :(得分: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));