From 8e75eb9e988e2aceea5577f76a4602bf24033983 Mon Sep 17 00:00:00 2001 From: Hossein Moein Date: Sun, 28 Jul 2024 11:48:58 -0400 Subject: [PATCH] Implemented ends_with() --- docs/HTML/DataFrame.html | 4 + docs/HTML/starts_with.html | 94 ++++++++++++++++++++++- include/DataFrame/Internals/DataFrame.tcc | 49 ++++++++++++ test/dataframe_tester_4.cc | 80 +++++++++++++++++-- 4 files changed, 217 insertions(+), 10 deletions(-) diff --git a/docs/HTML/DataFrame.html b/docs/HTML/DataFrame.html index 2a20ed67..d9ac887a 100644 --- a/docs/HTML/DataFrame.html +++ b/docs/HTML/DataFrame.html @@ -252,6 +252,10 @@

API Reference with code samples &# empty() + + ends_with( ) + + fill_missing( 2 ) diff --git a/docs/HTML/starts_with.html b/docs/HTML/starts_with.html index 79a421f6..98befc4e 100644 --- a/docs/HTML/starts_with.html +++ b/docs/HTML/starts_with.html @@ -39,6 +39,7 @@ Signature Description Parameters +

@@ -67,16 +68,44 @@
       
     
 
+    
+       
+        

+template<binary_array T>
+StlVecType<T>
+ends_with(const char *col_name,
+          const T &pattern) const; 
+        
+ + + This function determines if each item in the named column ends with the given pattern. The column type could be either a string or binary data. More precisely the column type could be any of the following:
+
+    std::string
+    std::basic_string<unsigned char>
+    std::basic_string<std::byte>
+    std::vector<char>
+    std::vector<unsigned char>
+    std::vector<std::byte>
+        
+ It returns a vector of chars with the same size as the named column. A 0 value means the corresponding element does not end with the pattern. A 1 value means the corresponding element does end with the pattern.
+ + + T: Type of the named column
+ col_name: Name of the column
+ pattern: A string or binary pattern to match
+ + +
static void test_starts_with()  {
 
     std::cout << "\nTesting starts_with( ) ..." << std::endl;
 
-    std::vector<std::string>                idx = { "XXDnh\1", "XXD974h", "fbbgd", "XXDoiendg\0\0", "yehtfg", "mnbvcd", "dfgsret", "jhnbdfg", "XXDomagdfert", "XXmj;'[-09",
-                                                    "XDimnaxcdf3", "207652234", "XXD", "XX" };
-    std::vector<std::string>                s1 = { "XXDnh\1", "XXD974h", "fbbgd", "XXDoiendg\0\0", "yehtfg", "mnbvcd", "dfgsret", "jhnbdfg", "XXDomagdfert", "XXmj;'[-09",
-                                                   "XDimnaxcdf3", "207652234", "XXD", "XX" };
+    std::vector<std::string>                idx = { "XXDnh\1", "XXD974h", "fbbgd", std::string("XXDoiendg\0\0", 11), "yehtfg", "mnbvcd", "dfgsret", "jhnbdfg", "XXDomagdfert",
+                                                    "XXmj;'[-09", "XDimnaxcdf3", "207652234", "XXD", "XX" };
+    std::vector<std::string>                s1 = { "XXDnh\1", "XXD974h", "fbbgd", std::string("XXDoiendg\0\0", 11), "yehtfg", "mnbvcd", "dfgsret", "jhnbdfg", "XXDomagdfert",
+                                                   "XXmj;'[-09", "XDimnaxcdf3", "207652234", "XXD", "XX" };
     std::vector<std::vector<unsigned char>> v1 = { { 8, 9, 10, 11, 12, 13, 14, 20, 22, 23, 30, 31, 32, 100 },
                                                    { 8, 9, 10, 11, 12, 13, 14, 20, 22, 23, 30, 31, 32, 100 },
                                                    { 11, 12, 13, 14, 20, 22, 23, 30, 31, 32, 100 },
@@ -123,6 +152,63 @@
         assert(res3 == out_res);
     }
 }
+
+// ----------------------------------------------------------------------------
+
+static void test_ends_with()  {
+
+    std::cout << "\nTesting ends_with( ) ..." << std::endl;
+
+    std::vector<std::string>                idx = { "nh\1XXD", "974hXXD", "fbbgd", std::string("oiendg\0\0XXD", 11), "yehtfg", "mnbvcd", "dfgsret", "jhnbdfg", "omagdfertXXD",
+                                                    "XXmj;'[-09", "XDimnaxcdf3", "207652234", "XXD", "XX" };
+    std::vector<std::string>                s1 = { "nh\1XXD", "974hXXD", "fbbgd", std::string("oiendg\0\0XXD", 11), "yehtfg", "mnbvcd", "dfgsret", "jhnbdfg", "omagdfertXXD",
+                                                   "XXmj;'[-09", "XDimnaxcdf3", "207652234", "XXD", "XX" };
+    std::vector<std::vector<unsigned char>> v1 = { { 12, 13, 14, 20, 22, 23, 30, 31, 32, 100, 8, 9, 10, 11 },
+                                                   { 12, 13, 14, 20, 22, 23, 30, 31, 32, 100, 8, 9, 10, 11 },
+                                                   { 11, 12, 13, 14, 20, 22, 23, 30, 31, 32, 100 },
+                                                   { 12, 13, 14, 20, 22, 23, 30, 31, 32, 100, 8, 9, 10, 11 },
+                                                   { 11, 12, 13, 14, 20, 22, 23, 30, 31, 32, 100 },
+                                                   { 11, 12, 13, 14, 20, 22, 23, 30, 31, 32, 100 },
+                                                   { 8, 9, 10 },
+                                                   { 100 },
+                                                   { 12, 13, 14, 20, 22, 23, 30, 31, 32, 100, 8, 9, 10, 11 },
+                                                   { 11, 12, 13, 14, 20, 22, 23, 30, 31, 32, 100 },
+                                                   { 23, 30, 31, 32, 100 }
+                                                 };
+    std::vector<double>                     d3 = { 15, 16, 15, 18, 19, 16, 21, 0.34, 1.56, 0.34, 2.3, 0.34, 19.0, 10 };
+    std::vector<int>                        i1 = { 22, 23, 24, 25, 99 };
+    StrDataFrame                            df;
+
+    df.load_data(std::move(idx),
+                 std::make_pair("str_col", s1),
+                 std::make_pair("col2", v1),
+                 std::make_pair("col_3", d3),
+                 std::make_pair("col_4", i1));
+
+    const auto  res1 = df.ends_with<std::string>("str_col", "XXD");
+
+    {
+        std::vector<char>  out_res = { 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0 };
+
+        assert(res1 == out_res);
+    }
+
+    const auto  res2 = df.ends_with<std::vector<unsigned char>>("col2", { 8, 9, 10, 11 });
+
+    {
+         std::vector<char>  out_res = { 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 };
+
+        assert(res2 == out_res);
+    }
+
+    const auto  res3 = df.ends_with<std::string>(DF_INDEX_COL_NAME, "XXD");
+
+    {
+        std::vector<char>  out_res = { 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0 };
+
+        assert(res3 == out_res);
+    }
+}
 

C++ DataFrame::starts_with(const char *col_name, const T &pattern) const { // ---------------------------------------------------------------------------- +template +template +typename +DataFrame>::template + StlVecType +DataFrame::ends_with(const char *col_name, const T &pattern) const { + + using res_t = StlVecType; + + const ColumnVecType *vec { nullptr }; + + if (! ::strcmp(col_name, DF_INDEX_COL_NAME)) + vec = (const ColumnVecType *) &(get_index()); + else + vec = (const ColumnVecType *) &(get_column(col_name)); + + const size_type col_s = vec->size(); + res_t result (col_s, char{ 0 }); + const auto thread_level = + (col_s < ThreadPool::MUL_THR_THHOLD) ? 0L : get_thread_level(); + auto lbd = + [&result, vec, &pattern = std::as_const(pattern)] + (size_type begin, size_type end) -> void { + for (auto idx = begin; idx < end; ++idx) { + const auto &val = (*vec)[idx]; + const size_type p_s = pattern.size(); + const size_type v_s = val.size(); + + if (v_s >= p_s) + result[idx] = + char(! std::memcmp(val.data() + (v_s - p_s), + pattern.data(), + p_s)); + } + }; + + if (thread_level > 2) { + auto futures = + thr_pool_.parallel_loop(size_type(0), col_s, std::move(lbd)); + + for (auto &fut : futures) fut.get(); + } + else lbd(size_type(0), col_s); + + return(result); +} + +// ---------------------------------------------------------------------------- + template template DataFrame> DataFrame:: diff --git a/test/dataframe_tester_4.cc b/test/dataframe_tester_4.cc index 0ee4ac31..2c2fe0ea 100644 --- a/test/dataframe_tester_4.cc +++ b/test/dataframe_tester_4.cc @@ -54,13 +54,13 @@ static void test_starts_with() { std::cout << "\nTesting starts_with( ) ..." << std::endl; std::vector idx = - { "XXDnh\1", "XXD974h", "fbbgd", "XXDoiendg\0\0", "yehtfg", "mnbvcd", - "dfgsret", "jhnbdfg", "XXDomagdfert", "XXmj;'[-09", "XDimnaxcdf3", - "207652234", "XXD", "XX" }; + { "XXDnh\1", "XXD974h", "fbbgd", std::string("XXDoiendg\0\0", 11), + "yehtfg", "mnbvcd", "dfgsret", "jhnbdfg", "XXDomagdfert", + "XXmj;'[-09", "XDimnaxcdf3", "207652234", "XXD", "XX" }; std::vector s1 = - { "XXDnh\1", "XXD974h", "fbbgd", "XXDoiendg\0\0", "yehtfg", "mnbvcd", - "dfgsret", "jhnbdfg", "XXDomagdfert", "XXmj;'[-09", "XDimnaxcdf3", - "207652234", "XXD", "XX" }; + { "XXDnh\1", "XXD974h", "fbbgd", std::string("XXDoiendg\0\0", 11), + "yehtfg", "mnbvcd", "dfgsret", "jhnbdfg", "XXDomagdfert", + "XXmj;'[-09", "XDimnaxcdf3", "207652234", "XXD", "XX" }; std::vector> v1 = { { 8, 9, 10, 11, 12, 13, 14, 20, 22, 23, 30, 31, 32, 100 }, { 8, 9, 10, 11, 12, 13, 14, 20, 22, 23, 30, 31, 32, 100 }, @@ -114,11 +114,79 @@ static void test_starts_with() { } // ---------------------------------------------------------------------------- + +static void test_ends_with() { + + std::cout << "\nTesting ends_with( ) ..." << std::endl; + + std::vector idx = + { "nh\1XXD", "974hXXD", "fbbgd", std::string("oiendg\0\0XXD", 11), + "yehtfg", "mnbvcd", "dfgsret", "jhnbdfg", "omagdfertXXD", + "XXmj;'[-09", "XDimnaxcdf3", "207652234", "XXD", "XX" }; + std::vector s1 = + { "nh\1XXD", "974hXXD", "fbbgd", std::string("oiendg\0\0XXD", 11), + "yehtfg", "mnbvcd", "dfgsret", "jhnbdfg", "omagdfertXXD", + "XXmj;'[-09", "XDimnaxcdf3", "207652234", "XXD", "XX" }; + std::vector> v1 = + { { 12, 13, 14, 20, 22, 23, 30, 31, 32, 100, 8, 9, 10, 11 }, + { 12, 13, 14, 20, 22, 23, 30, 31, 32, 100, 8, 9, 10, 11 }, + { 11, 12, 13, 14, 20, 22, 23, 30, 31, 32, 100 }, + { 12, 13, 14, 20, 22, 23, 30, 31, 32, 100, 8, 9, 10, 11 }, + { 11, 12, 13, 14, 20, 22, 23, 30, 31, 32, 100 }, + { 11, 12, 13, 14, 20, 22, 23, 30, 31, 32, 100 }, + { 8, 9, 10 }, + { 100 }, + { 12, 13, 14, 20, 22, 23, 30, 31, 32, 100, 8, 9, 10, 11 }, + { 11, 12, 13, 14, 20, 22, 23, 30, 31, 32, 100 }, + { 23, 30, 31, 32, 100 } }; + std::vector d3 = + { 15, 16, 15, 18, 19, 16, 21, 0.34, 1.56, 0.34, 2.3, 0.34, 19.0, 10 }; + std::vector i1 = { 22, 23, 24, 25, 99 }; + StrDataFrame df; + + df.load_data(std::move(idx), + std::make_pair("str_col", s1), + std::make_pair("col2", v1), + std::make_pair("col_3", d3), + std::make_pair("col_4", i1)); + + const auto res1 = df.ends_with("str_col", "XXD"); + + { + std::vector out_res = + { 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0 }; + + assert(res1 == out_res); + } + + const auto res2 = + df.ends_with>("col2", { 8, 9, 10, 11 }); + + { + std::vector out_res = + { 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }; + + assert(res2 == out_res); + } + + const auto res3 = df.ends_with(DF_INDEX_COL_NAME, "XXD"); + + { + std::vector out_res = + { 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0 }; + + assert(res3 == out_res); + } +} + +// ---------------------------------------------------------------------------- + int main(int, char *[]) { MyDataFrame::set_optimum_thread_level(); test_starts_with(); + test_ends_with(); return (0); }