As a feature request I would really like to see a reverse function in a Vector. It would either return new Vector with reversed order of elements or just reverse the same list (both are good for me). Empty Vector would just do nothing. That would be helpful for various scripts. It would be good to skip own implementations like this one in JS:
function ReverseVector(vector) {
if (vector.empty) {
return;
}
var i = 0;
var j = vector.size - 1;
while (i < j) {
vector.exchange(i, j);
i++;
j--;
}
}
You can usually go through a vector in reverse order as easily as in normal order, e.g.:
for (var i = v.size-1; i >= 0; --i) {
... v(i) ...
}
But if you need to pass the vector into one of the Opus functions then I can see how you might want a reverse method. Is that the kind of thing you need it for?
The first thing that crosses my mind when I see that part of code you wrote is efficiency. I guess that v(i) internally traverses the vector from start to find i-tish element each time in this "for" loop (so (v.size^2)/2 iterations in total). I'm also guessing that Enumerator object is much more efficient as it just traverses the list once without doing such elements counting with v(i) internally. Unfortunately there is no ReverseEnumerator (which also would be a convenient alternative to reversing a vector). But after all this whole thinking doesn't make much sense as efficiency shouldn't be a considerable issue in such scripts after all. So let's just answer your question:
I've just started to scriptise everything I do in Opus so I'm still not fully aware what would I need and what not. Now as you pointed that out - yes I think it would be useful for Opus functions as well. But where I encountered such need is when I started to design conditional functions that either have to traverse list of files I have in my lister forward or backward depending on the argument given or dialog selection. In such functions it is much easier to just reverse the list of files and do the main loop that does everything exactly the same in both orders than creating two different loops and branch on if conditions or conditionally manipulating index adding one or subtracting one depending on direction... but I'm aware it's all about code simplicity and even if I really need the reverse function I can write one myself (I did) but having it out of the box would be a nice touch.
With a vector, efficiency will be pretty much identical however you enumerate the list. Vectors are like arrays, not linked lists.
Any method of iteration will be much more efficient than moving or copying all the items to rearrange the vector, if that is the worry. (Especially as you'd then still need another iteration after that to do the real work.)
From an efficiency point of view, if you need to handle both forward and backward iterations in the same script, one solution is to have a function f(...) that handles each item in the vector, and then feed it elements in the required order:
if (reverse) {
for (var i = v.size-1; i >= 0; --i) { f(v(i)); }
} else {
for (var i = 0; i < v.size; ++i) { f(v(i)); }
}
(That could be made slightly more efficient by caching the v.size value in the 2nd/forward case, but it won't matter unless there is a huge number of items.)
Then they don't need to be copied or moved at all, and the main code within f(...) doesn't need to worry about which direction it's going on.
A reverse method might still make sense, for completeness. I'm just trying to gauge needs/priorities.
Edit: For completeness, I'd make a reverse copy of a vector like this:
var rev = DOpus.Create.Vector();
for (var i = v.size-1; i >= 0; --i) {
rev.push_back(v(i));
}
Thank you for your answer. It puts some light on how the vector is done internally and also explains how I can handle things differently in my scripts.
Extracting single iteration logic into another function (that you called "f") may be a little messy in my case as I'm storing some state during iteration (remembering latest file or which image had GPS metadata). I'm updating the state depending on various conditions. In such solution I would need to gather the state in single object and pass it to every "f" or just store it globally.
Anyway, I will rethink how I approach this problem so maybe I can get rid of reversing completely.