Array Vector
An array vector is a special type of vector used to store variable-length two-dimensional arrays. This article describes how to create array vectors and read from and write to them.
Create an Array Vector
The C++ API provides two ways to create an array vector.
Method 1
Create an array vector by providing the index and value arrays. The syntax is as follows:
static Vector* createArrayVector(VectorSP index, VectorSP value);
For details about index and value, see arrayVector.
Sample code
VectorSP index = Util::createVector(DT_INT, 0);
int indexData[3]{3, 6, 9};
index->appendInt(indexData, 3);
VectorSP value = Util::createVector(DT_LONG, 0);
long long valueData[9]{1, 2, 3, 1, 2, 3, 1, 2, 3};
value->appendLong(valueData, 9);
VectorSP v2 = Util::createArrayVector(index, value);
std::cout << v2->getString() << std::endl;
//output: [[1,2,3],[1,2,3],[1,2,3]]
Method 2
Create an array vector by specifying the type.
static Vector* createArrayVector(DATA_TYPE type, INDEX size, INDEX capacity = 0, bool fast = true, int extraParam = 0, void *data = NULL, INDEX *pindex = NULL, bool containNull = false);
Parameters
type: The element type, such as DT_LONG_ARRAY or DT_INT_ARRAY.
size: The initial size.
capacity: The capacity allocated during construction. Setting the capacity appropriately can improve insertion performance.
fast: A reserved parameter that is currently unused.
extraParam: Used when creating a DECIMAL array vector to pass the DECIMAL scale.
data: If initial elements are provided, use data to pass the contents of the value array. You do not need to free this memory manually. The Vector destructor releases it automatically with delete[].
pindex: If initial elements are provided, use pindex to pass the contents of the index array. You do not need to free this memory manually. The Vector destructor releases it automatically with delete[].
containNull: If you pass data, this parameter specifies whether data contains null values. true indicates that it does; the default is false, which indicates that it does not.
Sample code
int *indexData = new int[3]{3, 6, 9};
long long *valueData = new long long[9]{1, 2, 3, 1, 2, 3, 1, 2, 3};
VectorSP v3 = Util::createArrayVector(DT_LONG_ARRAY, 3, 3, true, 0, valueData, indexData);
std::cout << v3->getString() << std::endl;
// output: [[1,2,3],[1,2,3],[1,2,3]]
Append Data
Use the append method to add data. Append value to the end of the array vector, where value can be a vector or an array of vectors. The syntax is as follows:
bool append(const ConstantSP& value);
Sample code
long long data[3]{1, 2, 3};
VectorSP subv1 = Util::createVector(DT_LONG, 0);
subv1->appendLong(data, 3);
v3->append(subv1);
std::cout << v3->getString() << std::endl; //[[1,2,3],[1,2,3],[1,2,3],[1,2,3]]
VectorSP v4 = ConstantSP(v3)->getValue();
v3->append(v4);
std::cout << v3->getString() << std::endl; //[[1,2,3],[1,2,3],[1,2,3],[1,2,3],[1,2,3],[1,2,3],[1,2,3],[1,2,3]]
Read Data
The C++ API provides two ways to read data from an array vector.
Method 1
Use the get method to retrieve data by index. The syntax is as
follows:
ConstantSP get(INDEX index) const;
Sample code
VectorSP subv2 = v3->get(2);
std::cout << subv2->getString() << std::endl;
// [1,2,3]
Method 2
Retrieve the value and index arrays, and then use them to access the data. The syntax is as follows:
ConstantSP getSourceValue();
ConstantSP getSourceIndex();
Sample code
int *indexData = new int[3]{3, 9, 11};
long long *valueData = new long long[11]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
VectorSP v3 = Util::createArrayVector(DT_LONG_ARRAY, 3, 3, true, 0, valueData, indexData);
std::cout << v3->getString() << std::endl;
int maxLength = 10;
std::vector<long long> element(maxLength);
VectorSP value = dynamic_cast<FastArrayVector*>(v3.get())->getSourceValue();
VectorSP index = dynamic_cast<FastArrayVector*>(v3.get())->getSourceIndex();
const long long* valueBuf = value->getLongConst(0, value->size(), nullptr);
const int* indexBuf = index->getIndexConst(0, index->size(), nullptr);
int startIndex = 0;
int length = 0;
for(int i = 0; i < v3->size(); ++i){
length = indexBuf[i] - startIndex;
memcpy(element.data(), valueBuf + startIndex, length * sizeof(long long));
std::cout << "the " << i << " element: ";
for(int j = 0; j < length; ++j) {
std::cout << element[j] << " ";
}
std::cout << std::endl;
startIndex = indexBuf[i];
}
Complete Example
Create a table object with an array vector column, and write data to it.
#include "DolphinDB.h"
#include "Util.h"
#include <iostream>
#include <vector>
using namespace dolphindb;
using namespace std;
int main() {
try {
// 1. Define the table schema
int rowNum = 3;
int elementsPerRow = 3;
vector<string> colNames = { "id", "value" };
vector<DATA_TYPE> colTypes = { DT_INT, DT_DOUBLE_ARRAY };
// 2. Create an index vector
VectorSP indexVector = Util::createVector(DT_INDEX, rowNum, rowNum);
INDEX* pindex = indexVector->getIndexArray();
int cumulative = 0;
for (int i = 0; i < rowNum; ++i) {
cumulative += elementsPerRow;
pindex[i] = cumulative;
}
// 3. Create a value vector
VectorSP valueVector = Util::createVector(DT_DOUBLE, rowNum * elementsPerRow, rowNum * elementsPerRow);
int valueIndex = 0;
for (int i = 0; i < rowNum; ++i) {
for (int j = 0; j < elementsPerRow; ++j) {
valueVector->setDouble(valueIndex++, i * 3 + j + 0.1);
}
}
// 4. Create a array vector
VectorSP arrayVectorCol = Util::createArrayVector(indexVector, valueVector);
// 5. Create the id column
VectorSP idCol = Util::createVector(DT_INT, rowNum, rowNum);
for (int i = 0; i < rowNum; ++i) {
idCol->setInt(i, i);
}
// 6. Create the table
vector<ConstantSP> cols = { idCol, arrayVectorCol };
ConstantSP table = Util::createTable(colNames, cols);
// 7. Connect and upload
DBConnection conn;
conn.connect("127.0.0.1", 8848);
conn.login("admin", "123456", false);
conn.upload("myArrayVectorTable", table);
// 8. Verify
ConstantSP result = conn.run("select * from myArrayVectorTable;");
cout << "------ Data Verification ------" << endl;
cout << result->getString() << endl;
conn.close();
}
catch (const std::exception& e) {
cout << "Error: " << e.what() << endl;
return -1;
}
return 0;
}
