2

I have some elements in a QMap<double, double> a-element. Now I want to get a vector of some values of a. The easiest approach would be (for me):

int length = x1-x0;
QVector<double> retVec;
for(int i = x0; i < length; i++)
{
    retVec.push_back(a.values(i));
}

with x1 and x0 as the stop- and start-positions of the elements to be copied. But is there a faster way instead of using this for-loop?

Edit: With "faster" I mean both faster to type and (not possible, as pointed out) a faster execution. As it has been pointed out, values(i) is not working as expected, thus I will leave it here as pseudo-code until I found a better_working replacement.

arc_lupus
  • 3,942
  • 5
  • 45
  • 81
  • You ask if there is a faster way, but looking at your code, it doesn't look like it works at all. `QMap::values()` returns a `QList` so you are trying to add a `QList` as an element of a vector of doubles. Also, you map is full of doubles, and yet you use an integer as a key. – dtech Nov 14 '15 at 10:04
  • @ddriver: Noticed it, thanks! I will fix it as soon as I will find a possible replacement for it. – arc_lupus Nov 14 '15 at 10:34

2 Answers2

2

Maybe this works:

QVector<double>::fromList(a.values().mid(x0, length));

The idea is to get all the values as a list of doubles, extract the sublist you are interested in, thus create a vector from that list by means of an already existent static method of QVector .

EDIT

As suggested in the comments and in the updated question, it follows a slower to type but faster solution:

QVector<double> v{length};
auto it = a.cbegin()+x0;
for(auto last = it+length; it != last; it++) {
    v.push_back(it.value());
}

I assume that x0 and length take care of the actual length of the key list, so a.cbegin()+x0 is valid and it doesn't worth to add the guard it != a.cend() as well.

Community
  • 1
  • 1
skypjack
  • 49,335
  • 19
  • 95
  • 187
  • Easy to type, but not very efficient, as the entire map will be converted to a list, then the list will be clipped and converted to a vector. The most efficient way would be to iterate the range of the map and push the results in a vector which has reserved space for all the elements. – dtech Nov 14 '15 at 10:23
  • Absolutely right. Should I leave this response here as a possible solution or you suggest to delete it? – skypjack Nov 14 '15 at 10:25
  • It's ok, you can add that solution to your answer as well and make it full proof. After all the OP doesn't specify what he means by "faster", faster to type or faster to execute. – dtech Nov 14 '15 at 10:28
  • @ddriver: Updated my question with the necessary informations – arc_lupus Nov 14 '15 at 10:35
  • @arc_lupus - you can't have both. You can have fast to type, slow to execute, or slow to type, fast to execute. If you use that a lot, just write a function for it so you can reuse it and save yourself the typing. – dtech Nov 14 '15 at 10:37
  • @ddriver: Then I'll choose the fast execution method. – arc_lupus Nov 14 '15 at 10:38
  • Updated the response as suggested by ddriver. I left there both the solutions anyway. I hope the second example is right and reflect what had been suggested. Thank you for the comments. – skypjack Nov 14 '15 at 13:18
0

Try this, shouldn work, haven't tested it:

int length = x1-x0;
QVector<double> retVec;
retVec.reserve(length); // reserve to avoid reallocations
QMap<double, double>::const_iterator i = map.constBegin();
i += x0; // increment to range start
while (length--) retVec << i++.value(); // add value to vector and advance iterator

This assumes the map has actually enough elements, thus the iterator is not tested before use.

dtech
  • 47,916
  • 17
  • 112
  • 190