How to convert arrow::Array to std::vector? - c++
I have an Apache arrow array that is created by reading a file.
std::shared_ptr<arrow::Array> array;
PARQUET_THROW_NOT_OK(reader->ReadColumn(0, &array));
Is there a way to convert it to std::vector or any other native array type in C++?
You can use std::static_pointer_cast to cast the arrow::Array to, for example, an arrow::DoubleArray if the array contains doubles, and then use the Value function to get the value at a particular index. For example:
auto arrow_double_array = std::static_pointer_cast<arrow::DoubleArray>(array);
std::vector<double> double_vector;
for (int64_t i = 0; i < array->length(); ++i)
{
double_vector.push_back(arrow_double_array->Value(i));
}
See the latter part of the ColumnarTableToVector function in this example:
https://arrow.apache.org/docs/cpp/examples/row_columnar_conversion.html. In that example, table->column(0)->chunk(0) is a std::shared_ptr<arrow::Array>.
To learn more, I found it useful to click on various parts of the inheritance diagram tree here: https://arrow.apache.org/docs/cpp/classarrow_1_1_flat_array.html. For example, strings in an arrow::StringArray are accessed using a GetString function instead of a Value function.
This is just what I've pieced together from these links, johnathan's comment above, and playing around with a small example myself, so I'm not sure if this is the best way, as I'm quite new to this.
Related
Graph with std::vectors?
I thought that a cool way of using vectors could be to have one vector class template hold an two separate int variables for x/y-coordinates to graph. example: std::vector<int, int> *name*; // First int. being the x-intercept on a graph // Second int. being the y-intercept on a graph (I also understand that I could just make every even/odd location or two separate vectors to classify each x/y-coordinate, but for me I would just like to see if this could work) However, after making this vector type, I came across an issue with assigning which int within the vector will be written to or extracted from. Could anyone tell me how to best select and std::cout both x/y ints appropriately? P.S. - My main goal, in using vectors this way, is to make a very basic graph output to Visual Studio terminal. While being able to change individual x/y-intercepts by 'selecting' and changing if needed. These coordinates will be outputted to the terminal via for/while loops. Also, would anyone like to list out different ways to best make x/y-coordinates with different containers?
Your question rather broad, in other words it is asking for a bit too much. I will just try to give you some pointers from which you can work your way to what you like. A) equidistant x If your x values are equidistant, ie 0, 0.5, 1, 1.5 then there is no need to store them, simply use a std::vector<int> y; if the number of variables is not known at compile time, otherwise a std::array<int,N> y; B) arbitrary x There are several options that depend on what you actually want to do. For simply storing (x,y)-pairs and printing them on the screen, they all work equally well. map std::map<int,int> map_x_to_y = { { 1,1}, {2,4}, {3,9}}; // print on screen for (const auto& xy : map_x_to_y) { std::cout << xy.first << ":" xy.second; } a vector of pairs std::vector<std::pair<int,int>> vector_x_and_y = { { 1,1}, {2,4}, {3,9}}; Printing on screen is actually the same as with map. The advantage of the map is that it has its elements ordered, while this is not the case for the vector. C) not using any container For leightweight calculations you can consider to not store the (xy) pairs at all, but simply use a function: int fun(int x) { return x*x; } TL;DR / more focussed A vector stores one type. You cannot have a std::vector<int,int>. If you look at the documentation of std::vector you will find that the second template parameter is an allocator (something you probably dont have to care about for some time). If you want to store two values as one element in a vector you either have to use std::vector<std::pair<double,double>> or a different container. PS I used std::pair in the examples above. However, I do consider it as good practice to name things whenever I can and leave std::pair for cases when I simply cannot give names better than first and second. In this spirit you can replace std::pair in the above examples with a struct data_point { int x; int y; };
C++ passing by reference in constructor
So I am making a program in C++ and my main method has to construct an object that takes as a parameter a vector. This is my code: int main() { vector<Seller> *staff = new vector<Seller>; for (int i = 0; i < 50; i++) { staff->push_back(Seller(i)); } BookStore store(*staff); deque<Book> books; books = store.getBooks(); } So, these are some pretty simple Object-Oriented concepts I think. My goals are: First, initializing an empty vector of sellers. A Seller is an object that has a constructor: Seller(int i); And represents, of course, a seller. Then, I want to fill in the vector with actual Sellers. These are constructed in the for loop. Then, I want to create a Store, which takes as an argument the sellers that work there. Finally, I create a new deque called books, and I assign to it the value of books in the Store class. The initialisation of the Books deque is done in the constructor of the Store: Store::Store(vector<Seller> &sellers) { this->sellers = sellers; this->books = deque<Book> (100, "Harry Potter"); } So this is the code and I am wondering if I am making a mistake in the passing arguments to new constructors part. I am a bit confused when passing by reference so I am asking for a bit on help on that part. I have two main questions: 1) Are there any errors there, considering how I want to run my program? Consider also that in the rest of the main method (not included here) I constantly change the value of the books deque. 2) Is there any way to replace an element in a deque without having to erase and insert? Is there a built-in function replace? If not, is the below code going to work if I just want to replace a value in the deque? For example, if the deque is like that: 3 4 5 2 And it (an iterator) has value 2. Then I want the deque to become: 3 4 6 2 When doing: books.erase(it); books.insert(it, 6); Thanks for any tips or help!
OK, here a short analysis. Firstly, the unique real error I found: staff is defined as a pointer and is given a value with new but is never released. You should anyway avoid using raw pointers, so either create the object on the stack: vector<Seller> staff{}; or use a smart pointer auto staff = make_unique<vector<Seller>>{}; (you will then have to learn something about the ownership semantics, so as you still are a beginner I'd recommend the first solution). Then, notice how the line this->sellers = sellers; in Store::Store will make a copy of the sellers vector, which probably is not what you meant. If you wanted your store to reference the variable created on main(), you should redefine your Store as class Store { // ... vector<Seller>& sellers; //... }; and the constructor as Store::Store(vector<Seller> &sellers) : sellers{sellers} // reference member variables must be given a value before the body of the constructor begins { books = deque<Book> (100, "Harry Potter"); } For the same reason, your line books = store.getBooks(); will make a copy of the deque (but maybe in this case it was intended). Finally, C++ offers many container manipulating functions under the <algorithms> library. Take a look at the reference. But if you already have an iterator to the element you want to replace, you do not need such algorithms, just write: *it = 6;
Initialize a Matrix of Pairs in Constructor
I'm creating a boardgame (Tzaar if curious :D) in openGL and I need to initialize my logical board with the starting pieces in each place. In my Game classe I have the following variable: std::pair<char,int> logicBoard[17][9]; and want to initialize it in the constructor following somewhat this example: logicBoard[][] = { {(0,0),(0,0),(0,0),(0,0),('z',1),(0,0),(0,0),(0,0),(0,0)}, {(0,0),(0,0),(0,0),('c',1),(0,0),('z',1),(0,0),(0,0),(0,0)}, {(0,0),(0,0),('c',1),(0,0),('y',1),(0,0),('z',1),(0,0),(0,0)}, {(0,0),('c',1),(0,0),('b',1),(0,0),('y',1),(0,0),('z',1),(0,0)}, {('c',1),(0,0),('b',1),(0,0),('x',1),(0,0),('y',1),(0,0),('c',1)}, {(0,0),('b',1),(0,0),('a',1),(0,0),('x',1),(0,0),('b',1),(0,0)}, {('z',1),(0,0),('a',1),(0,0),('z',1),(0,0),('a',1),(0,0),('c',1)}, {(0,0),('y',1),(0,0),('c',1),(0,0),('c',1),(0,0),('b',1),(0,0)}, {('z',1),(0,0),('x',1),(0,0),(0,0),(0,0),('a',1),(0,0),('c',1)}, {(0,0),('y',1),(0,0),('z',1),(0,0),('z',1),(0,0),('b',1),(0,0)}, {('z',1),(0,0),('x',1),(0,0),('c',1),(0,0),('x',1),(0,0),('c',1)}, {(0,0),('y',1),(0,0),('a',1),(0,0),('x',1),(0,0),('y',1),(0,0)}, {('z',1),(0,0),('b',1),(0,0),('a',1),(0,0),('y',1),(0,0),('z',1)}, {(0,0),('c',1),(0,0),('b',1),(0,0),('y',1),(0,0),('z',1),(0,0)}, {(0,0),(0,0),('c',1),(0,0),('b',1),(0,0),('z',1),(0,0),(0,0)}, {(0,0),(0,0),(0,0),('c',1),(0,0),('z',1),(0,0),(0,0),(0,0)}, {(0,0),(0,0),(0,0),(0,0),('c',1),(0,0),(0,0),(0,0),(0,0)} }; But since I'm not so in depth of C++, don't know the easiest way of doing so. Want it to be easily modified too since the board will be sent to Prolog (with the game logic) program through sockets, so it returns the modified board again to this variable.
Why not use a Container to better management of your pairs? It would be like this: std::vector< std::pair<char,int> > logicBoard; logicBoard.push_back({0, 1}); logicBoard.push_back({'c', 1}); And so on... This way if you ever need, lets say, the size of your "array" you can simply use logicBoard.size();
I would define a typedef, and here is a compilable snippet typedef std::pair<char,int> P; P logicBoard[17][9] = { {P(0,0),P(0,0),P(0,0),P(0,0),P('z',1),P(0,0),P(0,0),P(0,0),P(0,0)}, {P(0,0),P(0,0),P(0,0),P('c',1),P(0,0),P('z',1),P(0,0),P(0,0),P(0,0)}, {P(0,0),P(0,0),P('c',1),P(0,0),P('y',1),P(0,0),P('z',1),P(0,0),P(0,0)}, {P(0,0),P('c',1),P(0,0),P('b',1),P(0,0),P('y',1),P(0,0),P('z',1),P(0,0)}, {P('c',1),P(0,0),P('b',1),P(0,0),P('x',1),P(0,0),P('y',1),P(0,0),P('c',1)}, {P(0,0),P('b',1),P(0,0),P('a',1),P(0,0),P('x',1),P(0,0),P('b',1),P(0,0)}, {P('z',1),P(0,0),P('a',1),P(0,0),P('z',1),P(0,0),P('a',1),P(0,0),P('c',1)}, {P(0,0),P('y',1),P(0,0),P('c',1),P(0,0),P('c',1),P(0,0),P('b',1),P(0,0)}, {P('z',1),P(0,0),P('x',1),P(0,0),P(0,0),P(0,0),P('a',1),P(0,0),P('c',1)}, {P(0,0),P('y',1),P(0,0),P('z',1),P(0,0),P('z',1),P(0,0),P('b',1),P(0,0)}, {P('z',1),P(0,0),P('x',1),P(0,0),P('c',1),P(0,0),P('x',1),P(0,0),P('c',1)}, {P(0,0),P('y',1),P(0,0),P('a',1),P(0,0),P('x',1),P(0,0),P('y',1),P(0,0)}, {P('z',1),P(0,0),P('b',1),P(0,0),P('a',1),P(0,0),P('y',1),P(0,0),P('z',1)}, {P(0,0),P('c',1),P(0,0),P('b',1),P(0,0),P('y',1),P(0,0),P('z',1),P(0,0)}, {P(0,0),P(0,0),P('c',1),P(0,0),P('b',1),P(0,0),P('z',1),P(0,0),P(0,0)}, {P(0,0),P(0,0),P(0,0),P('c',1),P(0,0),P('z',1),P(0,0),P(0,0),P(0,0)}, {P(0,0),P(0,0),P(0,0),P(0,0),P('c',1),P(0,0),P(0,0),P(0,0),P(0,0)} }; BTW depending on your Prolog interface that should be adaptable to actually exchange values. In case, maybe you want to keep P lowercase.
accessing multi-dimensional array element c++
I am trying to work with a multi-dimensional array in MSVS2010 console application, and I need to access members of a 2D array. I instantiate the array as Thing::Thing(int _n){ // size of the array this.m = _n; thing = new int*[m]; for(int ii = 0; ii < m; ii++){ thing[ii] = new int[m]; } } this is working fine. though when I go to do a operator=, or operator== that both use the similar structure of: Thing& Thing::operator=(const Thing & _thing){ for(int ii = 0; ii < m; ii++){ for(int jj = 0; jj < m; jj++){ thing[ii][jj] = _thing[ii][jj]; //error thrown on this line } } return *this; } this throws 2 errors binary "[": 'const Thing' does not define this operator or a conversion to a type acceptable to the predefined operator IntelliSense: no operator"[]" matches these operands this doesn't make sense as it is an array of type int, and the "[]" operators have not been altered not to mention that error highlighting only puts it under: _thing[ii][jj]; I can kinda live without the assignment operator, but I need the comparison operator to have functionality.
You should do: thing[ii][jj] = _thing.thing[ii][jj]; in your assignment loop. And you should also check if the array sizes for both (this and _thing) are the same: it may give a crash otherwise. You get an error because you are trying to use operator[] (indexing operator) on an object class Thing, not on its internal array. If you want to use the Thing class like an array you should define an indexing operator for it e.g.: int* Thing::operator[](int idx) { return thing[idx]; }
I think you've got your "thing"-s confused. Since: Thing& Thing::operator=(const Thing & _thing) you probably want to have: thing[ii][jj] = _thing.thing[ii][jj]; _thing is the Thing object _thing.thing is the multidimensional array
Thing is the class, thing is the member, thing the parameter... and you forgot that if you want to access the member in the operator= call then you should use _thing.thing. Your naming choice is quite bad, so bad that it even confused yourself while you were writing the code (and if it was easy for you to make a mistake now try to imagine how much easier would be for someone else to get confused by this code or even for you in a few months from now). What about calling for example the class Array instead, the member data and the parameter other? I also would suggest avoiding having leading underscores in names, they are ugly and dangerous at the same time (do you know all the C++ rules about where you can put underscores in names and how many of them you are allowed to use?). When designing a class or a function you have many things to consider and the class name or the function name is important but is one of the many factors. But for a data member or a variable you only have to choose the type and the name and both of them are most important choices. So please take the habit of thinking carefully to names, especially of variables. The relative importance is tremendous for them. Variables and data members are just names... the name is actually the only reason for which in programming we like to use variables (the computer instead only uses numeric addresses and is perfectly happy with them). About the class design you probably would also like defining operator[](int)... int *operator[](int index) { return data[index]; } By doing this you will be able to write code like Array a(m); a[0][0] = 42; without the need to explicitly refer to data (and, by the way, this addition would also make your original code working... but still fix the names!!).
boost::variant usage
I am developing GUI application via wxWidgets. It has 2 parts: GUI part and "Logic" part. I want to have Logic part totally independent on wxWidgets. But one component in the GUI returning wxVariant and I need to use it in the Logic part. So I am looking for a way to "convert" wxVariant to boost::variant wxVariant works like this: wxVariant v("37"); int i = v.GetInteger(); //i==37 So I am thinking something like string s = methodReturningWxVariant().GetString(); boost::variant bV(s); //later in code e.g bV.GetInt(); bV.GetBool(); Is it possible to use boost::Variant (or boost::Any) like this?
You can probably use boost::variant with some changes. To start with, you need to tell boost::variant which types it will be storing: boost::variant<int, string, bool> v; Since you probably will be using this type in a few places, you will probably want to create an alias for it. i.e. typedef boost::variant<int, string, bool> myvar; then you can use myvar directly: myvar x = "hello"; myvar y = 20; myvar z = false; to retrieve values: string s = boost::get<string>(x); int i = boost::get<int>(y); bool b = boost::get<bool>(z); If you attempt to get a different type than is stored in the variant, it will throw an exception. You can query the variant's type with the which() member function. It will return a 0-based index to the type the variant is currently holding. switch (x.which()) { case 0: // it's an int case 1: // it's a string case 2: // it's a bool }
Simple answer? No. You cannot convert via strings, this induces a loss of information and boost::variant does not automatically attempt to parse strings. I don’t know whether wxVariant offers an explicit conversion – in general, it may be difficult to convert to boost::variant without testing for special cases.
boost::variant (please don't capitalize 'v') works another way: you can only get back what you put inside. Think about it as a type-safe(r) union. Checking documenation and tutorial also won't hurt. Boost.Any library doesn't differ from Boost.Variant in this respect (what you put is what you get :) ), but boost::any is unbounded: you can store value of any type in boost::any, but in boost::variant you can only store what was declared by variant's template parameters.
boost::variant does not do conversion for you. There are other separate means to convert a string to an integer, such as strtol(), sscanf(), boost::lexical_cast<>()...