PDA

View Full Version : 2D array in Qt: QVector or QList



timmu
18th May 2012, 10:04
Hi,

I need to store strings in a 2D array (table). Example:

car train bike
boat car scooter
bus ship shuttle

What is the best way to do it (I don't use GUI, it's a console application)? QVector or QList?
Does anyone have instructions for declaring and constructing a 2D array of strings? The contents (but not the size) of the 2D array changes a lot during the runtime.

Is this an acceptable way:


QVector<QString> *array[3];
for(i=0; i<3; i++) {array[i] = new QVector<QString>(3);}


But then how do I fill this with data. This did not work:



array[0][0]="hello";


Thanks!

Zlatomir
18th May 2012, 12:33
Have you tried QVector<QVector<QString> >?

timmu
18th May 2012, 13:20
Thanks. Indeed I'm aware of that. However, I was unable to figure out how to use it. If someone could show how to initialize and assign 2D array this way, I'd be very thankful. I know this does not work (but why?):



QVector<QVector<QString> > array[3][3];
QString test="hello";
array[0][0]=test;

Zlatomir
18th May 2012, 14:10
QVector<QVector<QString> > vectorOfVectorsOfStrings;

for(int i = 0; i < 3; i++) //of course you might not want to init the vectors in a loop - this is just an example
{
QVector<QString> foo; //create a QVector of QStrings
foo.push_back("fooo");
foo.push_back("booo");
vectorOfVectorsOfStrings.push_back(foo); //add the created vector as a line in your 2D vector
}

for(int i = 0; i < vectorOfVectorsOfStrings.size(); i++)
{
for(int j = 0; j < vectorOfVectorsOfStrings[i].size(); j++)
{
//do stuff with the QString vectorOfVectorsOfStrings[i][j]
}
}

ChrisW67
18th May 2012, 21:34
If the size of the array is known and fixed you might as well use a simple array.

You cannot size the nested QVectors, i.e. to get a 3x5 array of empty QStrings, without either using a loop:


// 3x5 array
QVector<QVector<QString> > v1(3);
for(int outer = 0; outer < v1.size(); ++outer)
v1[outer].resize(5);
qDebug() << v1;


or a construct like:


// 3x5 array
typedef QVector<QString> inner;
typedef QVector<inner> outer;
outer v2(3, inner(5));
qDebug() << v2;

This second approach does allow initialising all the elements to the same, non default value:


// 3 x 5 "?"
outer v3(3, inner(5, "?"));
qDebug() << v3;

softmixt
10th September 2016, 15:10
QVector<QStringList> matrix{{"foo", "bar", "baz"}, {"hello", "world", "!"}};

qDebug() << "output: " << matrix[0];

//Will output : output: ("foo", "bar", "baz")

qDebug() << "output: " << matrix[0][1];

//Will output : "bar"

d_stranz
10th September 2016, 18:29
QVector<QStringList> matrix{{"foo", "bar", "baz"}, {"hello", "world", "!"}};

This is not a 2D array. It is a 1D QVector of 1D QList<QString>. It is not the same as a QVector< QVector< QString > > and there are very important differences in terms of memory usage and performance.

From the QList documentation:



The QList class is a template class that provides lists.

QList<T> is one of Qt's generic container classes. It stores items in a list that provides fast index-based access and index-based insertions and removals.

QList<T>, QLinkedList<T>, and QVector<T> provide similar APIs and functionality. They are often interchangeable, but there are performance consequences. Here is an overview of use cases:

QVector should be your default first choice. QVector<T> will usually give better performance than QList<T>, because QVector<T> always stores its items sequentially in memory, where QList<T> will allocate its items on the heap unless sizeof(T) <= sizeof(void*) and T has been declared to be either a Q_MOVABLE_TYPE or a Q_PRIMITIVE_TYPE using Q_DECLARE_TYPEINFO. See the Pros and Cons of Using QList for an explanation.

...

Note: QVector and QVarLengthArray both guarantee C-compatible array layout. QList does not. This might be important if your application must interface with a C API.

...

Internally, QList<T> is represented as an array of T if sizeof(T) <= sizeof(void*) and T has been declared to be either a Q_MOVABLE_TYPE or a Q_PRIMITIVE_TYPE using Q_DECLARE_TYPEINFO. Otherwise, QList<T> is represented as an array of T* and the items are allocated on the heap.

The array representation allows very fast insertions and index-based access. The prepend() and append() operations are also very fast because QList preallocates memory at both ends of its internal array. (See Algorithmic Complexity for details).

Note, however, that when the conditions specified above are not met, each append or insert of a new item requires allocating the new item on the heap, and this per item allocation will make QVector a better choice for use cases that do a lot of appending or inserting, because QVector can allocate memory for many items in a single heap allocation.

Note that the internal array only ever gets bigger over the life of the list. It never shrinks. The internal array is deallocated by the destructor and by the assignment operator, when one list is assigned to another.
...


If your 2D array is rectangular (i.e. has rows with the same number of columns for each row) then probably the best way is to allocate a 1D QVector< QString >:



QVector< QString > stringMatrix;
stringMatrix.resize( nRows * nCols );


This results in one contiguous data array and very efficient access to any member in it.

AIT RAI
23rd April 2017, 21:23
i want to creat a two-dimensional QVector of QLine which means in front of each line another line:

for(int i=0;i<symZqaq.size();i++)
{
QVector<QLineF> sym;
sym.append(L4);
sym.append(L5);
sym.append(L29);
sym.append(L25);
sym.append(L42);
sym.append(L26);
sym.append(L28);
sym.append(L31);
sym.append(L36);
sym.append(L44);
symZqaq.append(sym);
}
for(int i=0;i<symZqaq.size();i++)
{
for(int j=0;j<symZqaq[i].size();i++)
{
symZqaq.append(L9);
symZqaq.append(L12);
symZqaq.append(L24);
symZqaq.append(L30);
symZqaq.append(L27);
symZqaq.append(L43);
symZqaq.append(L7);
symZqaq.append(L2);
symZqaq.append(L6);
symZqaq.append(L3);
}
}
the problem is in last loop for erreur : no matching function for call to 'QVector<QVector<QLineF> >::push_back(QLineF&)'
symZqaq.push_back(L9);

any help plz

d_stranz
26th April 2017, 17:08
no matching function for call to 'QVector<QVector<QLineF> >:: push_back(QLineF&)'

"symZqaq" is a QVector of QVectors, not a QVector of QLines. You can't push a QLine onto symZqaq, only a QVector< QLine >. You did it correctly in the first loop. Use the same method in the nested loop.