Recently I had to do a quick "utility" page where I needed to see how many files from a directory listing had been recorded into a database. I've been writing about 98% of my CF code in script syntax but, since it was quick and easy, I did this quickly in tags because it was outputting directly to the browser. In doing so, I made an interesting discovery in that, when you use closures, even in tag based pages, you can write cfscript. Here's the example
- Get the directory listing:
<cfset alljs = directoryList(expandpath('/src'),true,"path","*.js")>
- Get the database listings and convert it to an array
<cfquery name="alljsQ" datasource="blah">
select * from sitefiles where filename like '%.js%'
</cfquery>
<cfset recordedFiles = valuelist(alljsQ.filename).listToArray()> - Use a filter function to weed out the files I'd already recorded
<cfset missingFiles = alljs.filter(function(item){
var foundFile=item.replacenocase(expandpath('/src\'),'','all').replace("\","/","all");
return recordedFiles.find(foundFile) eq 0; })> - Use a map function to do what I needed to do with the files not recorded
<cfset missingFiles.map(function(item){
var foundFile=item.replacenocase(expandpath('/src\'),'','all').replace("\","/","all");
writeOutput("<li>#foundFile#</li>");
})>
- 1. Using the filter and map functions make the code more "functional". If you're looking for a reason to experiment with the idea of functional code, here are two good reasons:
- It really diminishes the number of things you can screw up.
- You can do it, even using tag based code which might ease the process of moving into script
- In the filter function in step 3, I used the member function ".find()". This is the equivalent of ArrayFind(recordedFiles,foundFile) but is more readable. Incidentally, I actually used ".indexOf" but then was a bit thrown when I had to use "eq -1" until I remembered that the CF version is ".find" and therefore starts counting at 1 with 0 being "not found". The Java version is ".indexOf" which means it starts counting at 0 and therefore -1 is the "not found".
- In the map function, the "callback" or "closure" function that is passed in, can be written in cfscript without worrying about the <cfscript> tag and so on.
Perhaps obvious to everyone but I did this mostly without thinking and then was pleasantly surprised when it worked.
Comments
Post a Comment