Utility Function: PatternFind()

Another pattern based function.


<cffunction name="PatternFind" output="false" returntype="boolean">
    <cfargument name="pattern" type="string" required="true" />
    <cfargument name="string" type="string" required="true" />
    
    <cfset var local = StructNew() />
    
    <cfif IsSimpleValue(arguments.pattern)>
        <cfset arguments.pattern = CreateObject("java", "java.util.regex.Pattern").compile(arguments.pattern) />
    </cfif>
    
    <cfset local.matcher = arguments.pattern.matcher(arguments.string) >
    
    <cfreturn local.matcher.find() />
</cffunction>

 

Utility Functions: Java Regex Pattern Matching

Ok, so this time I have a trio of functions all to get at a key piece of Java regular expression matching: groups. Groups allow you to extract small snippets of a regular expression, and let you do a lot more with them then ColdFusion alone. Check out the whole bunch.

 

Utility Function: ListRemove() and ListRemoveNoCase()

I ran into a problem earlier where I needed to remove the elements of one list from another list I could have worked around it in a couple of ways, but I thought that I'd rather have a function to do this for me.

<cffunction name="ListRemove" output="false" returntype="string">
    <cfargument name="string1" type="string" required="true" />
    <cfargument name="string2" type="string" required="true" />
    <cfargument name="scope" type="string" required="false" default="all" />
    <cfargument name="delimiters" type="string" required="false" default="," />

    <cfset var returnValue = "" />
    <cfset var position = 0 />

    <cfif NOT ListFindNoCase("one,all", arguments.scope)>
        <cfthrow errorcode="ListRemove" message="Invalid argument SCOPE. Valid values are ONE and ALL." />
    </cfif>

    <cfloop list="#arguments.string1#" index="value" delimiters="#arguments.delimiters#">
        <cfset position = ListFind(arguments.string2, value, arguments.delimiters) />
        
        <cfif position gt 0 AND arguments.scope eq "one">
            <cfset arguments.string2 = ListDeleteAt(arguments.string2, position) />
        <cfelseif position eq 0>
            <cfset returnValue = ListAppend(returnValue, value, arguments.delimiters) />
        </cfif>
    </cfloop>

    <cfreturn returnValue />
</cffunction>

And that meant that I needed to make the case insensitive version as well.

<cffunction name="ListRemoveNoCase" output="false" returntype="string">
    <cfargument name="string1" type="string" required="true" />
    <cfargument name="string2" type="string" required="true" />
    <cfargument name="scope" type="string" required="false" default="all" />
    <cfargument name="delimiters" type="string" required="false" default="," />

    <cfset var returnValue = "" />
    <cfset var position = 0 />

    <cfif NOT ListFindNoCase("one,all", arguments.scope)>
        <cfthrow errorcode="ListRemove" message="Invalid argument SCOPE. Valid values are ONE and ALL." />
    </cfif>

    <cfloop list="#arguments.string1#" index="value" delimiters="#arguments.delimiters#">
        <cfset position = ListFindNoCase(arguments.string2, value, arguments.delimiters) />
        
        <cfif position gt 0 AND arguments.scope eq "one">
            <cfset arguments.string2 = ListDeleteAt(arguments.string2, position) />
        <cfelseif position eq 0>
            <cfset returnValue = ListAppend(returnValue, value, arguments.delimiters) />
        </cfif>
    </cfloop>

    <cfreturn returnValue />
</cffunction>

Click more for a view of example results against some test data.

 

Utility Function: StructExtract()

Working with ArgumentCollections reminded me that I sometimes wish that I had an easy way to pull out just a few values from a structure into a new structure. So I wrote one:


<cffunction name="StructExtract" output="false" returntype="struct">
    <cfargument name="struct" type="struct" required="true"/>
    <cfargument name="keyList" type="string" required="true"/>

    <cfset var returnStruct = StructNew() />

    <cfloop list="#UCase(arguments.keyList)#" index="key">
        <cfset returnStruct[key] = arguments.struct[key] />
    </cfloop>

    <cfreturn returnStruct />
</cffunction>

Example


<cfset struct1 = {
Naomi = "Sweet",
Kit = "Tough",
Christina = "Cocky"
} /
>


<cfdump var="#struct1#" labe="struct1"/>

<cfset struct2 = StructExtract(struct1, "naomi,kit") />

<cfdump var="#struct2#" labe="struct2"/>

 

Utility Function: PermanentRedirect()

I really can't take any credit for this one. The idea and the core code come from Pete Freitag's blog post "What CFLOCATION Does". Its probably not even original to wrap it in a function, but here it is any way.


<cffunction name="PermanentRedirect" output="false" returntype="void">
    <cfargument name="url" type="string" required="false" />
    
    <cfheader statuscode="301" statustext="Moved Permanently" />
    <cfheader name="Location" value="#arguments.url#" />
    
    <cfabort />
    
    <cfreturn />
</cffunction>

 

Utility Function: ArrayElementIsDefined()

The other day I was trying to be clever and use a multi dimensional array as a kind of look up table for cached results based on two values. For example:


<cfset array = ArrayNew(2) />

<cfif NOT (ArrayIsDefined(array, x) AND NOT ArrayIsDefined(array[x], y))>
<cfset array[x][y] = someFunction(x, y) />
</cfif>

<cfset result = array[x][y] />

And what did I discover? The system bulks and throws an error... apparently even though ArrayIsDefined() is supposed to tell you if values exist in an array, it can't do that until at least 1 value has entered the array.

While I could have just done something like set array[1][1] = 0, it wouldn't have been quite right (what if x and y are 1 for real?), and it didn't sit right with me that ArrayIsDefined() didn't work in this situation. Here is my stand in for ArrayIsDefined().


<cffunction name="ArrayElementIsDefined" output="false" returntype="boolean">
    <cfargument name="array" type="array" required="true" />
    <cfargument name="index" type="numeric" required="true" />
    
    <cfset var returnValue = false />
    
    <cftry>
        <cfset returnValue = ArrayIsDefined(arguments.array, arguments.index) />
        
        <cfcatch type="any">
            <!--- Do nothing, the return value is already false --->
        </cfcatch>
    </cftry>
    
    <cfreturn returnValue />
</cffunction>

 

More Entries

Jon Hartmann, July 2011

I'm Jon Hartmann and I'm a Javascript fanatic, UX/UI evangelist and former ColdFusion master. I blog about mysterious error messages, user interface design questions, and all things baffling and irksome about programming for the web.

Learn more about me on LinkedIn.