Signature Description Parameters

template<typename ... Ts>
DataFrame
get_data_by_idx(Index2D<IndexType> range) const;
        
It returns a DataFrame (including the index and data columns) containing the data from index begin to index end. This function assumes the DataFrame is consistent and sorted by index. The behavior is undefined otherwise. Ts: The list of types for all columns. A type should be specified only once.
range: The begin and end iterators for index specified with index values

template<typename ... Ts>
DataFrame
get_data_by_idx(const std::vector<IndexType> &values) const;
        
It returns a DataFrame (including the index and data columns) containing the data corresponding to the indices specified in "values" vector.
This method runs in O(n), where n is the number of indices, by creating a hash table of values. IndexType must be hash able.
NOTE: The returned DataFrame is in the same order as original DataFrame
Ts: The list of types for all columns. A type should be specified only once.
values: List of indices to copy data from

template<typename ... Ts>
DataFrameView<I>
get_view_by_idx(Index2D<IndexType> range) const;
        
It behaves like get_data_by_idx(range), but it returns a DataFrameView.
A view is a DataFrame that is a reference to the original DataFrame.
So if you modify anything in the view the original DataFrame will also be modified.
NOTE: There are certain operations that you cannot do with a view. For example, you cannot add/delete columns, etc.
NOTE: Although this is a const method, it returns a view. So, the data could still be modified through the returned view
Ts: The list of types for all columns. A type should be specified only once.
range: The begin and end iterators for index specified with index values

template<typename ... Ts>
DataFramePtrView<I>
get_view_by_idx(const std::vector<IndexType> &values) const;
        
It behaves like get_data_by_idx(values), but it returns a DataFramePtrView.
A view is a DataFrame that is a reference to the original DataFrame. So if you modify anything in the view the original DataFrame will also be modified.
NOTE: There are certain operations that you cannot do with a view. For example, you cannot add/delete columns, etc.
NOTE: Although this is a const method, it returns a view. So, the data could still be modified through the returned view
Ts: The list of types for all columns. A type should be specified only once.
values: List of indices to copy data from
static void test_get_view_by_idx_slicing()  {

    std::cout << "\nTesting get_view_by_idx()/slicing ..." << std::endl;

    std::vector<unsigned long>  idx =
        { 123450, 123451, 123452, 123453, 123454, 123455, 123456, 123457, 123458, 123459, 123460, 123461, 123462, 123466 };
    std::vector<double> d1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 };
    std::vector<double> d2 = { 8, 9, 10, 11, 12, 13, 14, 20, 22, 23, 30, 31, 32, 1.89};
    std::vector<double> d3 = { 15, 16, 17, 18, 19, 20, 21, 0.34, 1.56, 0.34, 2.3, 0.1, 0.89, 0.45 };
    std::vector<int>    i1 = { 22, 23, 24, 25, 99, 100, 101, 3, 2 };
    MyDataFrame         df;

    df.load_data(std::move(idx),
                 std::make_pair("col_1", d1),
                 std::make_pair("col_2", d2),
                 std::make_pair("col_3", d3),
                 std::make_pair("col_4", i1));

    typedef DataFrameView<unsigned long> MyDataFrameView;

    MyDataFrame     df2 =
        df.get_data_by_idx<double, int>(Index2D<MyDataFrame::IndexType> { 123452, 123460 });
    MyDataFrameView dfv =
        df.get_view_by_idx<double, int>(Index2D<MyDataFrame::IndexType> { 123452, 123460 });

    df.write<std::ostream, double, int>(std::cout);
    df2.write<std::ostream, double, int>(std::cout);
    dfv.write<std::ostream, double, int>(std::cout);

    dfv.get_column<double>("col_3")[0] = 88.0;
    assert(dfv.get_column<double>("col_3")[0] == df.get_column<double>("col_3")[2]);
    assert(dfv.get_column<double>("col_3")[0] == 88.0);
}

// -----------------------------------------------------------------------------

static void test_get_data_by_idx_values()  {

    std::cout << "\nTesting get_data_by_idx(values) ..." << std::endl;

    std::vector<unsigned long>  idx = { 123450, 123451, 123452, 123450, 123455, 123450, 123449 };
    std::vector<double> d1 = { 1, 2, 3, 4, 5, 6, 7 };
    std::vector<double> d2 = { 8, 9, 10, 11, 12, 13, 14 };
    std::vector<double> d3 = { 15, 16, 17, 18, 19, 20, 21 };
    std::vector<double> d4 = { 22, 23, 24, 25 };
    MyDataFrame         df;

    df.load_data(std::move(idx),
                 std::make_pair("col_1", d1),
                 std::make_pair("col_2", d2),
                 std::make_pair("col_3", d3),
                 std::make_pair("col_4", d4));

    MyDataFrame df2 =
        df.get_data_by_idx<double>(std::vector<MyDataFrame::IndexType> { 123452, 123455 });
    MyDataFrame df3 =
        df.get_data_by_idx<double>(std::vector<MyDataFrame::IndexType> { 123449, 123450 });

    assert(df2.get_index().size() == 2);
    assert(df2.get_column<double>("col_3").size() == 2);
    assert(df2.get_column<double>("col_2").size() == 2);
    assert(df2.get_index()[0] == 123452);
    assert(df2.get_index()[1] == 123455);
    assert(df2.get_column<double>("col_3")[0] == 17.0);
    assert(df2.get_column<double>("col_2")[1] == 12.0);
    assert(std::isnan(df2.get_column<double>("col_4")[1]));

    assert(df3.get_index().size() == 4);
    assert(df3.get_column<double>("col_3").size() == 4);
    assert(df3.get_column<double>("col_2").size() == 4);
    assert(df3.get_column<double>("col_1").size() == 4);
    assert(df3.get_index()[0] == 123450);
    assert(df3.get_index()[1] == 123450);
    assert(df3.get_index()[2] == 123450);
    assert(df3.get_index()[3] == 123449);
    assert(df3.get_column<double>("col_1")[0] == 1.0);
    assert(df3.get_column<double>("col_2")[2] == 13.0);
    assert(df3.get_column<double>("col_4")[0] == 22.0);
    assert(df3.get_column<double>("col_4")[1] == 25.0);
    assert(std::isnan(df3.get_column<double>("col_4")[2]));
    assert(std::isnan(df3.get_column<double>("col_4")[3]));
}

// -----------------------------------------------------------------------------

static void test_get_view_by_idx_values()  {

    std::cout << "\nTesting get_view_by_idx(values) ..." << std::endl;

    std::vector<unsigned long>  idx = { 123450, 123451, 123452, 123450, 123455, 123450, 123449 };
    std::vector<double> d1 = { 1, 2, 3, 4, 5, 6, 7 };
    std::vector<double> d2 = { 8, 9, 10, 11, 12, 13, 14 };
    std::vector<double> d3 = { 15, 16, 17, 18, 19, 20, 21 };
    std::vector<double> d4 = { 22, 23, 24, 25 };
    MyDataFrame         df;

    df.load_data(std::move(idx),
                 std::make_pair("col_1", d1),
                 std::make_pair("col_2", d2),
                 std::make_pair("col_3", d3),
                 std::make_pair("col_4", d4));

    auto    dfv1 =
        df.get_view_by_idx<double>(std::vector<MyDataFrame::IndexType> { 123452, 123455 });
    auto    dfv2 =
        df.get_view_by_idx<double>(std::vector<MyDataFrame::IndexType> { 123449, 123450 });

    assert(dfv1.get_index().size() == 2);
    assert(dfv1.get_column<double>("col_3").size() == 2);
    assert(dfv1.get_column<double>("col_2").size() == 2);
    assert(dfv1.get_index()[0] == 123452);
    assert(dfv1.get_index()[1] == 123455);
    assert(dfv1.get_column<double>("col_3")[0] == 17.0);
    assert(dfv1.get_column<double>("col_2")[1] == 12.0);
    assert(std::isnan(dfv1.get_column<double>("col_4")[1]));

    assert(dfv2.get_index().size() == 4);
    assert(dfv2.get_column<double>("col_3").size() == 4);
    assert(dfv2.get_column<double>("col_2").size() == 4);
    assert(dfv2.get_column<double>("col_1").size() == 4);
    assert(dfv2.get_index()[0] == 123450);
    assert(dfv2.get_index()[1] == 123450);
    assert(dfv2.get_index()[2] == 123450);
    assert(dfv2.get_index()[3] == 123449);
    assert(dfv2.get_column<double>("col_1")[0] == 1.0);
    assert(dfv2.get_column<double>("col_2")[2] == 13.0);
    assert(dfv2.get_column<double>("col_4")[0] == 22.0);
    assert(dfv2.get_column<double>("col_4")[1] == 25.0);
    assert(std::isnan(dfv2.get_column<double>("col_4")[2]));
    assert(std::isnan(dfv2.get_column<double>("col_4")[3]));

    dfv2.get_column<double>("col_1")[0] = 101.0;
    assert(dfv2.get_column<double>("col_1")[0] == 101.0);
    assert(df.get_column<double>("col_1")[0] == 101.0);
}