Skip to content

Instantly share code, notes, and snippets.

@DeveloperOfficeCom
Created July 19, 2025 14:56
Show Gist options
  • Select an option

  • Save DeveloperOfficeCom/147b539d6b54d5ac2123d6b3c10c9381 to your computer and use it in GitHub Desktop.

Select an option

Save DeveloperOfficeCom/147b539d6b54d5ac2123d6b3c10c9381 to your computer and use it in GitHub Desktop.
UniqueSet function for ColdFusion/Lucee - Set data structure for unique values with set operations
<!---
UNIQUESET Function
Description: Creates a set data structure that stores only unique values, similar to Python's set()
or JavaScript's Set(). Automatically prevents duplicates and provides set operations like union,
intersection, and difference.
Parameters:
- initialData: Optional data to initialize the set (array, string, or delimited list) (optional)
- delimiter: If initialData is a string, the delimiter to split on (optional, default: ",")
Returns: Set object with methods for unique value operations
Usage:
<cfset mySet = uniqueSet()>
<cfset mySet = uniqueSet([1, 2, 2, 3])>
<cfset mySet = uniqueSet("a,b,b,c", ",")>
Examples:
uniqueSet([1, 2, 2, 3]).toArray() returns [1, 2, 3]
uniqueSet().add("apple").add("banana").size() returns 2
setA.union(setB) returns combined unique values
Author: DeveloperOffice.com
Language: ColdFusion/Lucee
License: MIT (https://opensource.org/licenses/MIT)
Version: 1.0
--->
<cffunction name="uniqueSet" returntype="struct" output="false">
<cfargument name="initialData" type="any" required="false">
<cfargument name="delimiter" type="string" required="false" default=",">
<!--- Internal storage using struct for fast lookups --->
<cfset var data = structNew()>
<cfset var insertionOrder = arrayNew(1)>
<!--- Initialize with provided data --->
<cfif structKeyExists(arguments, "initialData")>
<cfif isArray(arguments.initialData)>
<!--- Initialize from array --->
<cfloop from="1" to="#arrayLen(arguments.initialData)#" index="i">
<cfset var value = arguments.initialData[i]>
<cfset var key = toString(value)>
<cfif NOT structKeyExists(data, key)>
<cfset data[key] = value>
<cfset arrayAppend(insertionOrder, value)>
</cfif>
</cfloop>
<cfelseif isSimpleValue(arguments.initialData)>
<!--- Initialize from delimited string --->
<cfif len(trim(arguments.initialData)) GT 0>
<cfset var items = listToArray(arguments.initialData, arguments.delimiter)>
<cfloop from="1" to="#arrayLen(items)#" index="i">
<cfset var value = trim(items[i])>
<cfset var key = toString(value)>
<cfif NOT structKeyExists(data, key)>
<cfset data[key] = value>
<cfset arrayAppend(insertionOrder, value)>
</cfif>
</cfloop>
</cfif>
</cfif>
</cfif>
<!--- Create the set wrapper --->
<cfset var setWrapper = structNew()>
<cfset setWrapper._data = data>
<cfset setWrapper._order = insertionOrder>
<!--- Add method to add values --->
<cfset setWrapper.add = function(value) {
<cfset var key = toString(arguments.value)>
<cfif NOT structKeyExists(this._data, key)>
<cfset this._data[key] = arguments.value>
<cfset arrayAppend(this._order, arguments.value)>
</cfif>
<cfreturn this>
}>
<!--- Remove method to remove values --->
<cfset setWrapper.remove = function(value) {
<cfset var key = toString(arguments.value)>
<cfif structKeyExists(this._data, key)>
<cfset structDelete(this._data, key)>
<!--- Remove from insertion order --->
<cfset var index = arrayFind(this._order, arguments.value)>
<cfif index GT 0>
<cfset arrayDeleteAt(this._order, index)>
</cfif>
<cfreturn true>
</cfif>
<cfreturn false>
}>
<!--- Has method to check if value exists --->
<cfset setWrapper.has = function(value) {
<cfset var key = toString(arguments.value)>
<cfreturn structKeyExists(this._data, key)>
}>
<!--- Size method to get count of unique values --->
<cfset setWrapper.size = function() {
<cfreturn structCount(this._data)>
}>
<!--- Clear method to remove all values --->
<cfset setWrapper.clear = function() {
<cfset structClear(this._data)>
<cfset arrayClear(this._order)>
<cfreturn this>
}>
<!--- ToArray method to get array of unique values --->
<cfset setWrapper.toArray = function() {
<cfreturn duplicate(this._order)>
}>
<!--- ToList method to get delimited string --->
<cfset setWrapper.toList = function(delimiter) {
<cfset var delim = ",">
<cfif structKeyExists(arguments, "delimiter")>
<cfset delim = arguments.delimiter>
</cfif>
<cfreturn arrayToList(this._order, delim)>
}>
<!--- Union method to combine with another set --->
<cfset setWrapper.union = function(otherSet) {
<cfset var result = uniqueSet()>
<!--- Add all values from this set --->
<cfloop from="1" to="#arrayLen(this._order)#" index="i">
<cfset result.add(this._order[i])>
</cfloop>
<!--- Add all values from other set --->
<cfif isStruct(arguments.otherSet) AND structKeyExists(arguments.otherSet, "_order")>
<cfloop from="1" to="#arrayLen(arguments.otherSet._order)#" index="i">
<cfset result.add(arguments.otherSet._order[i])>
</cfloop>
<cfelseif isArray(arguments.otherSet)>
<cfloop from="1" to="#arrayLen(arguments.otherSet)#" index="i">
<cfset result.add(arguments.otherSet[i])>
</cfloop>
</cfif>
<cfreturn result>
}>
<!--- Intersection method to find common values --->
<cfset setWrapper.intersection = function(otherSet) {
<cfset var result = uniqueSet()>
<!--- Check each value in this set against other set --->
<cfloop from="1" to="#arrayLen(this._order)#" index="i">
<cfset var value = this._order[i]>
<cfset var found = false>
<cfif isStruct(arguments.otherSet) AND structKeyExists(arguments.otherSet, "has")>
<cfset found = arguments.otherSet.has(value)>
<cfelseif isArray(arguments.otherSet)>
<cfset found = arrayContains(arguments.otherSet, value)>
</cfif>
<cfif found>
<cfset result.add(value)>
</cfif>
</cfloop>
<cfreturn result>
}>
<!--- Difference method to find values only in this set --->
<cfset setWrapper.difference = function(otherSet) {
<cfset var result = uniqueSet()>
<!--- Check each value in this set --->
<cfloop from="1" to="#arrayLen(this._order)#" index="i">
<cfset var value = this._order[i]>
<cfset var found = false>
<cfif isStruct(arguments.otherSet) AND structKeyExists(arguments.otherSet, "has")>
<cfset found = arguments.otherSet.has(value)>
<cfelseif isArray(arguments.otherSet)>
<cfset found = arrayContains(arguments.otherSet, value)>
</cfif>
<cfif NOT found>
<cfset result.add(value)>
</cfif>
</cfloop>
<cfreturn result>
}>
<!--- IsSubset method to check if this set is subset of another --->
<cfset setWrapper.isSubset = function(otherSet) {
<cfloop from="1" to="#arrayLen(this._order)#" index="i">
<cfset var value = this._order[i]>
<cfset var found = false>
<cfif isStruct(arguments.otherSet) AND structKeyExists(arguments.otherSet, "has")>
<cfset found = arguments.otherSet.has(value)>
<cfelseif isArray(arguments.otherSet)>
<cfset found = arrayContains(arguments.otherSet, value)>
</cfif>
<cfif NOT found>
<cfreturn false>
</cfif>
</cfloop>
<cfreturn true>
}>
<!--- IsSuperset method to check if this set contains another set --->
<cfset setWrapper.isSuperset = function(otherSet) {
<cfif isStruct(arguments.otherSet) AND structKeyExists(arguments.otherSet, "_order")>
<cfloop from="1" to="#arrayLen(arguments.otherSet._order)#" index="i">
<cfif NOT this.has(arguments.otherSet._order[i])>
<cfreturn false>
</cfif>
</cfloop>
<cfelseif isArray(arguments.otherSet)>
<cfloop from="1" to="#arrayLen(arguments.otherSet)#" index="i">
<cfif NOT this.has(arguments.otherSet[i])>
<cfreturn false>
</cfif>
</cfloop>
</cfif>
<cfreturn true>
}>
<!--- Equals method to check if sets are equal --->
<cfset setWrapper.equals = function(otherSet) {
<cfif isStruct(arguments.otherSet) AND structKeyExists(arguments.otherSet, "size")>
<cfreturn this.size() EQ arguments.otherSet.size() AND this.isSubset(arguments.otherSet)>
</cfif>
<cfreturn false>
}>
<!--- IsEmpty method --->
<cfset setWrapper.isEmpty = function() {
<cfreturn this.size() EQ 0>
}>
<cfreturn setWrapper>
</cffunction>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment