Skip to content

Instantly share code, notes, and snippets.

@bennadel
Created Mar 25, 2014
Embed
What would you like to do?
Ask Ben: Delete Values In A Given List Using ColdFusion
<cffunction
name="ListDeleteValue"
access="public"
returntype="string"
output="false"
hint="Deletes a given value (or list of values) from a list. This is not case sensitive.">
<!--- Define arguments. --->
<cfargument
name="List"
type="string"
required="true"
hint="The list from which we want to delete values."
/>
<cfargument
name="Value"
type="string"
required="true"
hint="The value or list of values that we want to delete from the first list."
/>
<cfargument
name="Delimiters"
type="string"
required="false"
default=","
hint="The delimiting characters used in the given lists."
/>
<!--- Define the local scope. --->
<cfset var LOCAL = StructNew() />
<!---
Create an array in which we will store our new list.
This will be faster than building a list via string
concatenation.
--->
<cfset LOCAL.Result = ArrayNew( 1 ) />
<!---
Convert the target list into an array for faster
list iteration.
--->
<cfset LOCAL.ListArray = ListToArray(
ARGUMENTS.List,
ARGUMENTS.Delimiters
) />
<!---
Convert our value list into struct. This will allow us
to do super fast value look ups to see if we have a
value requires deletion. We aren't going to bother
converting this list to an array first (as we did above)
because the likely scenario is that we won't have many
values (and generally only one).
--->
<cfset LOCAL.ValueLookup = StructNew() />
<!--- Loop over value list to create index. --->
<cfloop
index="LOCAL.ValueItem"
list="#ARGUMENTS.Value#"
delimiters="#ARGUMENTS.Delimiters#">
<!--- Create index entry. --->
<cfset LOCAL.ValueLookup[ LOCAL.ValueItem ] = true />
</cfloop>
<!---
Now that we have our index in place, it's time to start
looping over the target list and looking for target
values in our index. NOTE: Since our index is a struct,
the lookups will NOT be case sensisitve.
--->
<cfloop
index="LOCAL.ValueIndex"
from="1"
to="#ArrayLen( LOCAL.ListArray )#"
step="1">
<!--- Get a short hand to the current list value. --->
<cfset LOCAL.Value = LOCAL.ListArray[ LOCAL.ValueIndex ] />
<!--- Check to see if this value is in the index. --->
<cfif NOT StructKeyExists(
LOCAL.ValueLookup,
LOCAL.Value
)>
<!---
We are not deleting this value so add it to
the taret array.
--->
<cfset ArrayAppend(
LOCAL.Result,
LOCAL.Value
) />
</cfif>
</cfloop>
<!---
At this point, our target list has been trimmed and
stored in the results array. Now, we have to convert
the array back to a list. This poses a little bit of
complication: we can only use one delimiter. Therefore,
we might lose some meaningful delimiters. This has been
done in the tradeoff for faster processing.
--->
<cfreturn ArrayToList(
LOCAL.Result,
Left( ARGUMENTS.Delimiters, 1 )
) />
</cffunction>
<!--- Create a multi-delimited list. --->
<cfset lstNumbers = "1,1,2,2:3:3,4,4:5:5,6,6:7:7,8,8:9:9" />
<cfset lstOddNumbers = ListDeleteValue(
lstNumbers,
"2,4,6,8",
",:"
) />
<!--- Output odd values. --->
#lstOddNumbers#
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment