From a8a80f0dc449863c924161223579e1d66a8a8e0e Mon Sep 17 00:00:00 2001 From: Yi Zhang Date: Thu, 2 Jan 2025 19:29:24 +0800 Subject: [PATCH] add filter to dsv_io --- example/text_io_ex.cpp | 4 +++ lib/io/dsv_io.cpp | 81 ++++++++++++++++++++++++++++++++++++++++++ lib/io/dsv_io.h | 20 +++++++++++ 3 files changed, 105 insertions(+) diff --git a/example/text_io_ex.cpp b/example/text_io_ex.cpp index d5bd8fd..ed22339 100644 --- a/example/text_io_ex.cpp +++ b/example/text_io_ex.cpp @@ -82,6 +82,10 @@ int main(int argc, char const *argv[]) try tc.add_row(3); tc.fill_row(array{5.5, 4.4, 3.3, 2.2, 1.1}, 3); + geodsv_io out_table; + tc.filter("dist > 1000", {"dist"}, {"x (m)", "y (m)", "elev (m)"}, out_table); + out_table.save_text("out2"); + _1s_vector s = tc.get_tags(); s.push_back("Elev = 1000"); tc.set_tags(s); diff --git a/lib/io/dsv_io.cpp b/lib/io/dsv_io.cpp index 977a228..470f9bc 100644 --- a/lib/io/dsv_io.cpp +++ b/lib/io/dsv_io.cpp @@ -362,6 +362,28 @@ void gctl::dsv_io::init_table(int row, int col, table_headtype_e t) return; } +void gctl::dsv_io::init_table(const std::vector > &str_table, table_headtype_e t) +{ + row_num_ = str_table.size(); + col_num_ = str_table[0].size(); + + // 初始的列头和行头均为空白 + table_.resize(row_num_ + 1); + for (size_t i = 0; i < row_num_ + 1; i++) + { + table_[i].resize(col_num_ + 1); + } + + for (size_t i = 1; i <= row_num_; i++) + { + for (size_t j = 1; j <= col_num_; j++) + { + table_[i][j].str_ = str_table[i - 1][j - 1]; + } + } + return; +} + void gctl::dsv_io::info(table_headtype_e t) { std::clog << "File: " << file_ << "\n------------\n"; @@ -637,6 +659,65 @@ void gctl::dsv_io::cal_column(std::string expr_str, const std::vector &cnd_col, + const std::vector &out_col, dsv_io& out_table) +{ + array idx(cnd_col.size()); + for (size_t i = 0; i < cnd_col.size(); i++) + { + idx[i] = name_index(cnd_col[i]); + } + + array odx(out_col.size()); + for (size_t i = 0; i < out_col.size(); i++) + { + odx[i] = name_index(out_col[i]); + } + + exprtk::symbol_table symbol_table; + array var(cnd_col.size()); + + for (size_t i = 0; i < var.size(); i++) + { + symbol_table.add_variable(cnd_col[i], var[i]); + } + + exprtk::expression expression; + expression.register_symbol_table(symbol_table); + + exprtk::parser parser; + if (!parser.compile(cnd_str, expression)) + { + throw std::runtime_error("[gctl::dsv_io] Fail to compile the math expression."); + } + + std::vector str_line; + std::vector > str_table; + + for (size_t i = 1; i <= row_num_; i++) + { + for (size_t j = 0; j < var.size(); j++) + { + var[j] = table_[i][idx[j]].value(); + } + + if (expression.value() > 0.5) // return 1 if matched or 0 if dismatched + { + str_line.clear(); + for (size_t j = 0; j < odx.size(); j++) + { + str_line.push_back(table_[i][odx[j]].str_); + } + + str_table.push_back(str_line); + } + } + + out_table.init_table(str_table); + out_table.set_column_names(out_col); + return; +} + #endif // GCTL_EXPRTK gctl::geodsv_io::geodsv_io(){} diff --git a/lib/io/dsv_io.h b/lib/io/dsv_io.h index aeab508..f789d07 100644 --- a/lib/io/dsv_io.h +++ b/lib/io/dsv_io.h @@ -352,9 +352,18 @@ namespace gctl * * @param row 数据行数 * @param col 数据列数 + * @param t 表格头类型 */ void init_table(int row, int col, table_headtype_e t = ColumnHead); + /** + * @brief 初始化表格 + * + * @param str_table 字符串表格 + * @param t 表格头类型 + */ + void init_table(const std::vector > &str_table, table_headtype_e t = ColumnHead); + /** * @brief 返回表格信息 * @@ -463,6 +472,17 @@ namespace gctl */ void cal_column(std::string expr_str, const std::vector &col_list, int p = 6); + /** + * @brief 按行过滤并返回符合条件的列数据 + * + * @param cnd_str 条件表达式 + * @param cnd_col 用于条件表达式的列索引列表 + * @param out_col 输出的列索引列表,即条件判断为真是即筛选这些行与列上对应的数据 + * @param out_table 输出的表格 + */ + void filter(std::string cnd_str, const std::vector &cnd_col, + const std::vector &out_col, dsv_io &out_table); + #endif // GCTL_EXPRTK /**