Let's think about this differently.
If we rewrite these in cfscript for illustrative purposes:
myArray=[ 'xyz', 'yyy', '232', 'uoiu', 'youneedthis', '2343'];
writedump(myArray);
myLongStringThing = '';
// LOOP OVER AN INDEX AND MANUALLY PUSH YOUR ARRAY ALONG
for ( i = 1; i <= myArray.size(); i++) {
v = myArray[i];
if(i < 5 && i > 1 && myArray[i] != myArray[i-1] ){
x = doSomethingComplicated(v);
myArray[i] = x; // Your new computed value
}
if(i > 1 && v != myArray[i-1] ) {
y = somethingElseCool(v);
myLongStringThing &= y;
}
}
writedump(myArray);
writeoutput(myLongStringThing & '<br>');
// LOOP THE VALUES IN THE STRUCT/ARRAY
i = 0;
for (k in myArray) {
i++;
writeoutput('k:' & k & '<br>');
writeoutput('a[i]:' & myArray[i] & '<br>');
}
function doSomethingComplicated(v) {
Arguments.v &= 'you did it!';
return Arguments.v;
}
function somethingElseCool(v) {
Arguments.v &= ';';
return Arguments.v;
}
// LOOPING A STRUCT IS DIFFERENT
myStruct = {'asdf' = 234234, 'sdfsd' = 9798, 'oiujlkj3' = 'kohjkjh'};
for (k in myStruct) {
writeoutput('kinstruct:' & k & '<br>');
writeoutput('kinstruct:' & myStruct[k] & '<br>');
}
If we consider the attribute signature of cfloop as the same as using for(counter;condition;incrementor)
vs. for(valuekey in object)
we see they are roughly the same thing.
You can choose how to iterate over your object (array) but you can't choose the value only version and have the current iterators keep track of the index for you.
So if you need to track your prev/next index, you need to choose an iterator method that allows an index (even if it is manually done).
NB: For an array, you can probably mix/match a keyvalue with a manual iterator (the for(k in obj)
style) but when a structure is used, it is the actual KEY name that is returned into 'k'. Not the value of the iterated array. This is in line with the cfloop attribute signature of looping over a collection (eg: structure).
I think you are asking for the cfloop to let you set both a value and index attribute marker. And I realize other languages (and dialects) might do this, but so far in CF, nope.
The edge cases are easily manageable with a compound if statement.
You can use the exact same compound logic in the if statements in tags to account for the edge cases as well.
You may have noticed I used size()
instead of ArrayLen()
. There are a few java operators you can use on arrays. However, none that give you the 'cursor' or index of a given state as far as I can tell.
If you want to delve into arrays a bit more, you can create a java version of the array and do a few more things:
myArray = CreateObject( "java", "java.util.ArrayList" );
writeDump(myArray); // This will show you the java object, which needs to be 'inited' still.
myArray = myArray.init(); // It returns the array, it does not act on the orig obj.
// You can now access the vast majority of java methods (including the parent methods)
myArray.add('myFirstValue');
myArray.add('my2ndValue');
myArray.add('yetAnotherValue');
writeDump(myArray);// This will look like a regular array dump
// You can also apply regular CF functions to this array like arrayAppend().
x = myArray.get(1); // This is a java index, so it begins at 0 which is the 1st elem. 1 is 2nd, etc.
writeOuput('At java index 1 we have:' & x & '<br>');
You can play with a few of those but none of them will return a usable cursor or index as far as I can tell. A few might be handy though, like subList() and equals().
Ultimately, if you want to find the index without keeping a manual index, you can do this:
index = arrayFind(myArray, v)
Which of course is just a look-up of the index by value, assuming the value is unique. Using one of the loop methods that uses an index seems safer rather than trying to figure out where you are after the fact.