如何按任意列对数据进行动态排序
How to dynamically sort data by arbitrary column(s)
是否有一种结构组合的数据结构(STL、Boost等)允许我像在这里的表中那样对内存中的数据进行排序http://en.wikipedia.org/wiki/List_of_cities_proper_by_population
我想要一个通用的解决方案,可以处理任意数量和列名称。本质上相似使用sql的order by clause
好吧,你必须做一些腿部工作。
构造一个结构或元组以容纳一行的编译器:
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
这可以通过有一个向量的向量而变得通用,并且比较函数可以从它的环境中捕获变量:参见我的另一个答案
有Boost.Multi-index。不过,您需要提前指定要为其构建索引的所有列。
如果您在SQL中order by
一个没有索引的列,它只会进行线性扫描并动态构建一个排序的结果集——如果您想按某个没有预先索引的列排序,那么在C++中也可以这样做。
OK,因此基于以下假设:
- 要按名称选择排序列吗
- 您想为每一行存储类似
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);
}
我会制作一个结构向量,每个结构为该表的1"行"建模。您可以使用std::sort和sort functor按不同的成员对其进行排序,sort funtor只比较您想要排序的成员。
我想我会单独发布一个通用答案
考虑:
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));
相关文章:
- 在 c++ 中对类中的 c 字符串动态数组进行排序的最佳方法是什么?
- 合并排序C++帮助 为合并的数字动态分配临时数组
- openMp 动态调度与按处理时间排序任务时的 LPT 调度相同吗?
- 使用动态数组对算法编译器错误进行排序
- 使用向量和气泡排序的动态内存分配
- 尝试创建排序的动态列表(数据结构)
- "Debug assertion failed" 这种有什么问题?它应该按年份对包含电影对象的动态列表进行排序
- 快速排序动态大量对象无法正常工作
- 冒泡排序无法对C++中的对象的动态数组进行排序
- C 排序字符串的动态阵列 - 排序不起作用
- 使用数据文件对动态数组进行排序
- 合并排序中的动态内存分配
- 对动态大小的对象进行排序
- C++按属性排序的对象动态数组
- 堆损坏 使用动态数组进行气泡排序时出错
- 使用用户定义的动态容器对元素进行排序
- 对 2D 动态数组进行排序 C++
- 如何使用 calloc/malloc 等函数对动态创建的存储进行正确排序,使其以 FIFO 方式运行
- 使用冒泡排序对随机数量的动态数组进行排序
- 如何按任意列对数据进行动态排序