“#coldfusion 9 tip -grab a handle on the iterator of an array by calling someArray.iterator(). then u can use that in script FOR/WHILE loops!"
I never thought of that, so I wanted to give it a whirl.
<cfscript> //pre-cf8 list = "one,two,three,four"; a = listToArray(list); for(i=1; i LTE ArrayLen(a); i=i+1){ writeoutput(a[i]); } //traditionally, with cf8+ syntax a = ["one","two","three","four"]; for(i=1; i <= ArrayLen(a); i++){ writeoutput(a[i]); } //with an iterator //uncomment if you want to see what's available: writedump(a.iterator()); iter = a.iterator(); while(iter.hasNext()){ el = iter.next(); writeOutput(el); } </cfscript>
Warning: don’t try to skip the iter = a.iterator() and el = iter.next() steps in an effort to save a few lines of code! If you try to loop while(a.iterator().hasNext()), you’ll get stuck in an endless loop because you’ll be returning a new iterator each time. And each time you call iter.next(), you’re advancing through the array; thus, doing writeOutput(iter.next()); doSomethingWithThisElement(iter.next()); will give you very different results from what you’re expecting. You’ve been warned.
Thanks for the tip, Micky!
9 comments:
I wish CF9 add the for..in loop support for array. Looping an array is easier using <cfloop array=""> than cfscript.
good tip,marc! challenged me to see if i could make it smaller ... i wonder just how small a cf loop could be?
for(i=-1;++ilt;myarray.size();) {
...myarray.get(i);
}
Mark Mandel pointed out that this may be slower since it uses reflection via JavaProxy. Something to consider!
-Mick
last post on this promise.
using a java arraylist with iterator is 500x faster than cf's for loop and cf for loop using iterator.
createobject("java", "java.util.ArrayList");
-Mick
great information guys. Thanks.
Micky, your friend needn't decompile if he simply wants to see the inheritance tree, available methods, etc. I whipped this up really quick to give a quick and dirty view of a CF Array, but you could use this for just about any cf datatype. note this is literally about 15 minutes of work, just to give me a fast idea of what's what:
<cfscript>
a = ["one","two"];
writedump(var=getMetadata(a),expand=false);
s = {key1="hi mom",key2=a};
writedump(var=getMetadata(s),expand=false);
writedump(createDirtyStructView(a));
writedump(createDirtyStructView(s));
public struct function createDirtyStructView(someVar){
var cls = someVar.getClass();
var data = {className=cls.getName(),exceptions=[],methods=[],interfaces=[],parent=cls.getSuperClass().getName(),tree=[]};
var classes = cls.getClasses();
var methods = cls.getMethods();
var interfaces = cls.getSuperClass().getInterfaces();
var i = 1;
//writeDump(methods);
for(i=1;i<=ArrayLen(classes);i++){
arrayAppend(data.exceptions,classes[i].getName());
}
for(i=1;i<=ArrayLen(methods);i++){
arrayAppend(data.methods,methods[i].getName());
}
for(i=1;i<=ArrayLen(interfaces);i++){
arrayAppend(data.interfaces,interfaces[i].getName());
}
var thisParentClass = cls;
var thisParentName = thisParentClass.getName();
arrayPrepend(data.tree,thisParentName);
var sentry = 100;
while(thisParentName != "java.lang.Object" && i < sentry){
thisParentClass = thisParentClass.getSuperClass();
thisParentName = thisParentClass.getName();
arrayPrepend(data.tree,thisParentName);
i++;
}
return data;
}
</cfscript>
@Marc
Once again, another great tip to file away. very cool!
-Mick
just a thought : you don't have to convert the list into an array. you can also use:
list = "ten,eleven,twelve";
for (j=1; j lte ListLen(list); j++) {
writeOutput('...');
writeOutput(listGetAt(list,j) & '
');
}
Useful function Marc ... Thanks ;-)
Post a Comment