Created
July 19, 2025 20:00
-
-
Save DeveloperOfficeCom/589c3bcc1f81e7d1627ad76f1956d106 to your computer and use it in GitHub Desktop.
ColdFusion implementation of set operations utility - Provides union, intersection, difference, and other mathematical set operations on arrays
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ColdFusion implementation of set operations utility - Provides union, intersection, difference, and other mathematical set operations on arrays | |
| <!--- | |
| SETOPERATIONS Function | |
| Description: Provides utility methods for performing mathematical set operations on arrays without | |
| needing to create set objects. Includes union, intersection, difference, and other common set operations | |
| that work directly with arrays. | |
| Parameters: None - returns an object with set operation methods | |
| Returns: Struct with methods for set operations | |
| Usage: | |
| <cfset ops = setoperations()> | |
| <cfset result = ops.union([1,2,3], [3,4,5])> | |
| <cfset result = ops.intersection(arr1, arr2)> | |
| Examples: | |
| ops.union([1,2,3], [3,4,5]) returns [1,2,3,4,5] | |
| ops.intersection([1,2,3], [2,3,4]) returns [2,3] | |
| ops.difference([1,2,3], [2,4]) returns [1,3] | |
| Author: DeveloperOffice.com | |
| Language: ColdFusion/Lucee | |
| License: MIT (https://opensource.org/licenses/MIT) | |
| Version: 1.0 | |
| ---> | |
| <cffunction name="setoperations" returntype="struct" output="false"> | |
| <!--- Create the operations wrapper ---> | |
| <cfset var operations = structNew()> | |
| <cfset var privateThis = structNew()> | |
| <!--- Union: All unique elements from both arrays ---> | |
| <cfset privateThis.union = _setoperations_union> | |
| <cfset operations.union = privateThis.union> | |
| <!--- Intersection: Common elements between arrays ---> | |
| <cfset privateThis.intersection = _setoperations_intersection> | |
| <cfset operations.intersection = privateThis.intersection> | |
| <!--- Difference: Elements in first array but not in second ---> | |
| <cfset privateThis.difference = _setoperations_difference> | |
| <cfset operations.difference = privateThis.difference> | |
| <!--- Symmetric Difference: Elements in either array but not in both ---> | |
| <cfset privateThis.symmetricDifference = _setoperations_symmetricDifference> | |
| <cfset operations.symmetricDifference = privateThis.symmetricDifference> | |
| <!--- Is Subset: Check if all elements of array1 are in array2 ---> | |
| <cfset privateThis.isSubset = _setoperations_isSubset> | |
| <cfset operations.isSubset = privateThis.isSubset> | |
| <!--- Is Superset: Check if array1 contains all elements of array2 ---> | |
| <cfset privateThis.isSuperset = _setoperations_isSuperset> | |
| <cfset operations.isSuperset = privateThis.isSuperset> | |
| <!--- Are Equal: Check if arrays contain same unique elements ---> | |
| <cfset privateThis.areEqual = _setoperations_areEqual> | |
| <cfset operations.areEqual = privateThis.areEqual> | |
| <!--- Unique: Remove duplicates from single array ---> | |
| <cfset privateThis.unique = _setoperations_unique> | |
| <cfset operations.unique = privateThis.unique> | |
| <!--- Contains: Check if array contains a value ---> | |
| <cfset privateThis.contains = _setoperations_contains> | |
| <cfset operations.contains = privateThis.contains> | |
| <!--- Is Disjoint: Check if arrays have no common elements ---> | |
| <cfset privateThis.isDisjoint = _setoperations_isDisjoint> | |
| <cfset operations.isDisjoint = privateThis.isDisjoint> | |
| <!--- Cartesian Product: All possible pairs from two arrays ---> | |
| <cfset privateThis.cartesianProduct = _setoperations_cartesianProduct> | |
| <cfset operations.cartesianProduct = privateThis.cartesianProduct> | |
| <!--- Power Set: All possible subsets of an array ---> | |
| <cfset privateThis.powerSet = _setoperations_powerSet> | |
| <cfset operations.powerSet = privateThis.powerSet> | |
| <cfreturn operations> | |
| </cffunction> | |
| <!--- Helper Functions ---> | |
| <cffunction name="_setoperations_union" output="false" returntype="array"> | |
| <cfargument name="array1" type="array" required="true"> | |
| <cfargument name="array2" type="array" required="true"> | |
| <cfset var result = arrayNew(1)> | |
| <cfset var seen = structNew()> | |
| <cfset var i = 0> | |
| <cfset var key = ""> | |
| <!--- Add all elements from first array ---> | |
| <cfloop from="1" to="#arrayLen(arguments.array1)#" index="i"> | |
| <cfset key = toString(arguments.array1[i])> | |
| <cfif NOT structKeyExists(seen, key)> | |
| <cfset arrayAppend(result, arguments.array1[i])> | |
| <cfset seen[key] = true> | |
| </cfif> | |
| </cfloop> | |
| <!--- Add unique elements from second array ---> | |
| <cfloop from="1" to="#arrayLen(arguments.array2)#" index="i"> | |
| <cfset key = toString(arguments.array2[i])> | |
| <cfif NOT structKeyExists(seen, key)> | |
| <cfset arrayAppend(result, arguments.array2[i])> | |
| <cfset seen[key] = true> | |
| </cfif> | |
| </cfloop> | |
| <cfreturn result> | |
| </cffunction> | |
| <cffunction name="_setoperations_intersection" output="false" returntype="array"> | |
| <cfargument name="array1" type="array" required="true"> | |
| <cfargument name="array2" type="array" required="true"> | |
| <cfset var result = arrayNew(1)> | |
| <cfset var seen1 = structNew()> | |
| <cfset var seen2 = structNew()> | |
| <cfset var added = structNew()> | |
| <cfset var i = 0> | |
| <cfset var key = ""> | |
| <!--- Build lookup for first array ---> | |
| <cfloop from="1" to="#arrayLen(arguments.array1)#" index="i"> | |
| <cfset key = toString(arguments.array1[i])> | |
| <cfset seen1[key] = arguments.array1[i]> | |
| </cfloop> | |
| <!--- Build lookup for second array ---> | |
| <cfloop from="1" to="#arrayLen(arguments.array2)#" index="i"> | |
| <cfset key = toString(arguments.array2[i])> | |
| <cfset seen2[key] = arguments.array2[i]> | |
| </cfloop> | |
| <!--- Find common elements ---> | |
| <cfloop collection="#seen1#" item="key"> | |
| <cfif structKeyExists(seen2, key) AND NOT structKeyExists(added, key)> | |
| <cfset arrayAppend(result, seen1[key])> | |
| <cfset added[key] = true> | |
| </cfif> | |
| </cfloop> | |
| <cfreturn result> | |
| </cffunction> | |
| <cffunction name="_setoperations_difference" output="false" returntype="array"> | |
| <cfargument name="array1" type="array" required="true"> | |
| <cfargument name="array2" type="array" required="true"> | |
| <cfset var result = arrayNew(1)> | |
| <cfset var seen2 = structNew()> | |
| <cfset var added = structNew()> | |
| <cfset var i = 0> | |
| <cfset var key = ""> | |
| <!--- Build lookup for second array ---> | |
| <cfloop from="1" to="#arrayLen(arguments.array2)#" index="i"> | |
| <cfset key = toString(arguments.array2[i])> | |
| <cfset seen2[key] = true> | |
| </cfloop> | |
| <!--- Add elements from first array that aren't in second ---> | |
| <cfloop from="1" to="#arrayLen(arguments.array1)#" index="i"> | |
| <cfset key = toString(arguments.array1[i])> | |
| <cfif NOT structKeyExists(seen2, key) AND NOT structKeyExists(added, key)> | |
| <cfset arrayAppend(result, arguments.array1[i])> | |
| <cfset added[key] = true> | |
| </cfif> | |
| </cfloop> | |
| <cfreturn result> | |
| </cffunction> | |
| <cffunction name="_setoperations_symmetricDifference" output="false" returntype="array"> | |
| <cfargument name="array1" type="array" required="true"> | |
| <cfargument name="array2" type="array" required="true"> | |
| <cfset var diff1 = _setoperations_difference(arguments.array1, arguments.array2)> | |
| <cfset var diff2 = _setoperations_difference(arguments.array2, arguments.array1)> | |
| <cfreturn _setoperations_union(diff1, diff2)> | |
| </cffunction> | |
| <cffunction name="_setoperations_isSubset" output="false" returntype="boolean"> | |
| <cfargument name="array1" type="array" required="true"> | |
| <cfargument name="array2" type="array" required="true"> | |
| <cfset var seen2 = structNew()> | |
| <cfset var i = 0> | |
| <cfset var key = ""> | |
| <!--- Build lookup for second array ---> | |
| <cfloop from="1" to="#arrayLen(arguments.array2)#" index="i"> | |
| <cfset key = toString(arguments.array2[i])> | |
| <cfset seen2[key] = true> | |
| </cfloop> | |
| <!--- Check if all elements of array1 are in array2 ---> | |
| <cfloop from="1" to="#arrayLen(arguments.array1)#" index="i"> | |
| <cfset key = toString(arguments.array1[i])> | |
| <cfif NOT structKeyExists(seen2, key)> | |
| <cfreturn false> | |
| </cfif> | |
| </cfloop> | |
| <cfreturn true> | |
| </cffunction> | |
| <cffunction name="_setoperations_isSuperset" output="false" returntype="boolean"> | |
| <cfargument name="array1" type="array" required="true"> | |
| <cfargument name="array2" type="array" required="true"> | |
| <cfreturn _setoperations_isSubset(arguments.array2, arguments.array1)> | |
| </cffunction> | |
| <cffunction name="_setoperations_areEqual" output="false" returntype="boolean"> | |
| <cfargument name="array1" type="array" required="true"> | |
| <cfargument name="array2" type="array" required="true"> | |
| <cfset var unique1 = _setoperations_unique(arguments.array1)> | |
| <cfset var unique2 = _setoperations_unique(arguments.array2)> | |
| <cfif arrayLen(unique1) NEQ arrayLen(unique2)> | |
| <cfreturn false> | |
| </cfif> | |
| <cfreturn _setoperations_isSubset(unique1, unique2)> | |
| </cffunction> | |
| <cffunction name="_setoperations_unique" output="false" returntype="array"> | |
| <cfargument name="array" type="array" required="true"> | |
| <cfset var result = arrayNew(1)> | |
| <cfset var seen = structNew()> | |
| <cfset var i = 0> | |
| <cfset var key = ""> | |
| <cfloop from="1" to="#arrayLen(arguments.array)#" index="i"> | |
| <cfset key = toString(arguments.array[i])> | |
| <cfif NOT structKeyExists(seen, key)> | |
| <cfset arrayAppend(result, arguments.array[i])> | |
| <cfset seen[key] = true> | |
| </cfif> | |
| </cfloop> | |
| <cfreturn result> | |
| </cffunction> | |
| <cffunction name="_setoperations_contains" output="false" returntype="boolean"> | |
| <cfargument name="array" type="array" required="true"> | |
| <cfargument name="value" type="any" required="true"> | |
| <cfset var i = 0> | |
| <cfset var searchKey = toString(arguments.value)> | |
| <cfset var elementKey = ""> | |
| <cfloop from="1" to="#arrayLen(arguments.array)#" index="i"> | |
| <cfset elementKey = toString(arguments.array[i])> | |
| <cfif elementKey EQ searchKey> | |
| <cfreturn true> | |
| </cfif> | |
| </cfloop> | |
| <cfreturn false> | |
| </cffunction> | |
| <cffunction name="_setoperations_isDisjoint" output="false" returntype="boolean"> | |
| <cfargument name="array1" type="array" required="true"> | |
| <cfargument name="array2" type="array" required="true"> | |
| <cfset var intersection = _setoperations_intersection(arguments.array1, arguments.array2)> | |
| <cfreturn arrayLen(intersection) EQ 0> | |
| </cffunction> | |
| <cffunction name="_setoperations_cartesianProduct" output="false" returntype="array"> | |
| <cfargument name="array1" type="array" required="true"> | |
| <cfargument name="array2" type="array" required="true"> | |
| <cfset var result = arrayNew(1)> | |
| <cfset var i = 0> | |
| <cfset var j = 0> | |
| <cfset var pair = ""> | |
| <cfloop from="1" to="#arrayLen(arguments.array1)#" index="i"> | |
| <cfloop from="1" to="#arrayLen(arguments.array2)#" index="j"> | |
| <cfset pair = arrayNew(1)> | |
| <cfset arrayAppend(pair, arguments.array1[i])> | |
| <cfset arrayAppend(pair, arguments.array2[j])> | |
| <cfset arrayAppend(result, pair)> | |
| </cfloop> | |
| </cfloop> | |
| <cfreturn result> | |
| </cffunction> | |
| <cffunction name="_setoperations_powerSet" output="false" returntype="array"> | |
| <cfargument name="array" type="array" required="true"> | |
| <cfset var result = arrayNew(1)> | |
| <cfset var subsetCount = 2^arrayLen(arguments.array)> | |
| <cfset var i = 0> | |
| <cfset var j = 0> | |
| <cfset var subset = ""> | |
| <cfloop from="0" to="#subsetCount - 1#" index="i"> | |
| <cfset subset = arrayNew(1)> | |
| <cfloop from="0" to="#arrayLen(arguments.array) - 1#" index="j"> | |
| <cfif bitAnd(i, 2^j) GT 0> | |
| <cfset arrayAppend(subset, arguments.array[j + 1])> | |
| </cfif> | |
| </cfloop> | |
| <cfset arrayAppend(result, subset)> | |
| </cfloop> | |
| <cfreturn result> | |
| </cffunction> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment