Friday, August 7, 2026

ColdFusion - Cheatsheet 101 - Basic Functions

You don't have hours to spend ramping up on ColdFusion.
You need to get in. Get out and deliver. That's why I wrote this cheatsheet from the previous posts.

It's all the basic functions: Lists, Strings, Arrays and Structures.

But Sarg... you started with Lists. Why didn't you start with Strings first?

That would make more sense, right? No. Absolutely not. Your life consists of Lists far more than Strings.

Case in-point: Your life.

Answer these questions.
Where are you at the grocery store? In a line. That's a list.
Gas station paying cash? A line... a list.
And your tasty chicken strips at Chick-fil-A?
In the fastest line on planet earth because they have THE GREATEST customer service! That's a list too.

When I was a kid at school, we had a lunch line.
Every day, more than hundred kids.
I saw other kids cut-in AT THE START of the line. Right at the start of the line.
What's that? Besides being just wrong.

It's called a prepend. Adding to the front.
ColdFusion has those functions built-in for Lists and Arrays.
Merry Christmas!  See listPrepend and arrayPrepend

Get the free Cheatsheet!

Use the Contact form. I'll send it directly to your inbox. (formats: PDF, html and docx)

Privacy Policy: SPAM -- hated more than dirty boots on inspection day. Won't do it... EVER.

Thursday, July 30, 2026

ColdFusion Loop Structures - The 5 Minute Mission

You don't have hours to spend ramping up on ColdFusion.
You need to get in. Get out and deliver. Let's do that.

Copy and paste this into a cffiddle.org session.
Yep. Remember to wrap it with <cfscript> tags. Feel free to thank me in the comments.

// ---------------------------------------------------------------------------------------
// Tutorials with a SMART Mission
// What does that look like?

// SMART: Specific, Measurable, Achievable, Revelant and Time-bound
// S: Loop through Structures
// M: Read and digest within 5 minutes
// A: Anyone new/familiar with programing can use them immediately
// R: Use a data in a common ways anyone will mentally and emotionally connnect with
// T: Read within 3 min, Research more within seconds and Experiment with immediately.
// ---------------------------------------------------------------------------------------

// A struct is a key/value container. No index. No promises about order.
pantryStruct = {
    "Apples": 12,
    "Bananas": 6,
    "Carrots": 20,
    "Milk": 2,
    "Bread": 4
};

// A struct of structs (nested). Category -> its own pantry struct.
groceryStruct = {
    "Fruits": {"Apples": 12, "Bananas": 6, "Grapes": 30},
    "Veggies": {"Carrots": 20, "Broccoli": 5}
};

missionIntroduction = "
    <p><b>ColdFusion Loops - Structures</b><br>
    Remember Structure Functions? We are talking about looping today.  Welcome to another workout.</p>

    <p><b>MISSION:</b> Operation Groceries. Count what Mama's got in the pantry.</p>

    <p><b>VITAL DATA</b><br>
    <b>pantryStruct</b> (#structCount(pantryStruct)# items): #serializeJSON(pantryStruct)#<br><br>
    <b>groceryStruct</b> (#structCount(groceryStruct)# categories): #serializeJSON(groceryStruct)#</p>

    <p><b>NEED TO KNOW</b><br>
    <b>No Guaranteed Order:</b> Arrays and lists loop in order, 1 to the end. Structs don't play that game.<br>
    A struct is a bag of keys, not a line of Humvees. Loop it twice, you might get two different orders.<br>
    Need a guaranteed order? Sort the keys yourself, or build the struct with <b>structNew('ordered')</b>.</p>
";
writeOutput(missionIntroduction);

writeOutput("<b>EXAMPLES</b><br>");

// 1. Loop through struct with for-in (order not guaranteed)
writeOutput("<p>1. Loop through pantryStruct (key/value) - For-In<br>");
writeOutput("<strong>Pantry:</strong><br>");
for (key in pantryStruct) {
    writeOutput(key & ": " & pantryStruct[key] & "<br>");
}
writeOutput("</p>"); // outputs each key/value pair, order may vary run to run

// 2a. Loop through struct with structEach (closure-based)
writeOutput("<p>2a. Loop through pantryStruct - structEach (closure)<br>");
writeOutput("<strong>Pantry:</strong><br>");
structEach(pantryStruct, function(key, value) {
    writeOutput(key & ": " & value & "<br>");
});
writeOutput("</p>"); // same job as for-in, just handed off to a function

// 2b. Loop through struct in sorted key order
writeOutput("<p>2b. Loop through pantryStruct in A-Z order - structKeyArray + arraySort<br>");
writeOutput("<strong>Pantry (sorted):</strong><br>");
sortedKeys = structKeyArray(pantryStruct); // pull the keys out into an array
arraySort(sortedKeys, "textnocase"); // now THAT array can be ordered
for (key in sortedKeys) {
    writeOutput(key & ": " & pantryStruct[key] & "<br>");
}
writeOutput("</p>"); // outputs Apples, Bananas, Bread, Carrots, Milk - guaranteed, because you forced it

// 3. Loop through a nested struct (loop within a loop)
writeOutput("<p>3. Loop through groceryStruct (nested) - For-In inside For-In<br>");
writeOutput("<strong>Groceries by Category:</strong><br>");
for (category in groceryStruct) {
    writeOutput("<u>" & category & "</u><br>");
    categoryStruct = groceryStruct[category];
    for (item in categoryStruct) {
        writeOutput("  " & item & ": " & categoryStruct[item] & "<br>");
    }
}
writeOutput("</p>"); // each category prints its own items underneath it

// Include any additional information that helps summarizes the above examples
additionalPoints = "<br><hr>
<p>
 <b>Additional Points:</b>
 <ul>
  <li><b>Empty Structs:</b> Same deal as empty lists and arrays. Nothing in it, the loop body never runs. It won't do jack-squat.</li>
  <li><b>for-in vs. structEach:</b> They do the same job. for-in reads cleaner in most scripts. structEach hands the work to a function with some decent features.</li>
  <li><b>Order Matters? Sort It:</b> Don't assume insertion order. Pull structKeyArray, sort it, then loop the sorted array.  With that, you won't be doing KP, the other guy will.</li>
 </ul>
 </p>";
writeOutput(additionalPoints);

Let me know if I've missed your favorite loop. Or better yet point me to another site where everyone can learn about a riveting loop for structures from ColdFusion.

MORE INPUT
After you've climbed the rope and rung the bell of this code, go have a look at ColdFusion documentation at Adobe and Foundeo's CFDocs.

You can also take a look at Ben Nadel's article on using Structs as Data Lookup Indices.

Wednesday, July 29, 2026

ColdFusion Structures - The 5 Minute Mission

You don't have hours to spend ramping up on ColdFusion.
You need to get in. Get out and deliver. Let's do that.

Copy and paste this into a cffiddle.org session.
Yep. Remember to wrap it with <cfscript> tags. Feel free to thank me in the comments.

// Tutorials with a SMART Mission
// What does that look like?

// SMART: Specific, Measurable, Achievable, Revelant and Time-bound
// S: Structure Functions
// M: Read and digest within 5 minutes
// A: Anyone new/familiar with programing can use them immediately
// R: Use a data in a common ways anyone will mentally and emotionally connnect with
// T: Read within 3 min, Research more within seconds and Experiment with immediately.
// ---------------------------------------------------------------------------------------

// ColdFusion structures are variables that have a "key" and "data" format
fruitStruct = {
    "A": "Apples", 
    "B": "Bananas", 
    "C": "Cantaloupe", 
    "G": "Grapes", 
    "K": "Kiwi", 
    "O": "Oranges", 
    "P": "Pomegranate",
    "S": "Strawberries", 
    "W": "Watermelon" 
};
meatStruct = {
    "B": "Beef", 
    "C": "Chicken", 
    "F": "Fish", 
		"L": "Lamb",
    "P": "Pork",
    "T": "Turkey"
};

missionIntroduction = "
    <p><b>ColdFusion Structure Functions</b><br>
    As a CF developer, you use these often. Pick these up. You gonna need all 6 of 'em.</p>

    <p><b>MISSION:</b> Operation Groceries. Go help your Mama with these two structures.</p>

    <p><b>VITAL DATA</b><br>
    <b>Fruits</b> (#structCount(fruitStruct)#): #serializeJSON(fruitStruct)#<br> 
    <b>Meat</b> (#structCount(meatStruct)#): #serializeJSON(meatStruct)#</p>

    <p><b>NEED TO KNOW</b><br>
		<b>Keys:</b> The keys of a structure are not case-sensitive by default.<br>
    In Adobe ColdFusion, you can define them as case-sensitive if you want to since CF 2021.<br>
    Lucee does not have this feature.  Sorry Charlie!  Now you know.</p>
";
writeOutput(missionIntroduction);

writeOutput("<b>EXAMPLES</b><br>");

// 1. structCount - Count items in Struct
totalFruits = structCount(fruitStruct);
writeOutput("1. <b>structCount(fruitStruct)</b><br>Total Fruit Count: #totalFruits#<br>");

// 2. structInsert - add to struct (a struct is not linear, it just a container)
structInsert(fruitStruct, "M", "Mangoes"); // Add Mangoes to the structure
writeOutput("2. <b>structInsert(fruitStruct, 'M', 'Mangoes')</b><br>" & serializeJSON(fruitStruct) & "<br>");

// What if the Key already exists?  structInsert will fail.  See structKeyExists function
try { 
  structInsert(fruitStruct, "M", "Monkfruit", false);
}
catch(any e) { 
  writeOutput("<br><em>ATTEMPT & FAIL</em>");
  writeOutput("<br>TASK: Try to insert a key that already exists");
	writeOutput(" - <b>structInsert(fruitStruct, 'M', 'Monkfruit', false)</b>");
	writeOutput("<br>ERROR INFO<br>Message: #e.message#<br>Detail: #e.detail#<br><br>");
}

// 3. structKeyExists - Check existence and if it does exist, show key's value
favoriteFruit = "Not yet found";
keyToFind = "K";  // Feel free to change this to "Q" to prove when Key does not exist
writeOutput("3. <b>structKeyExists(fruitStruct, #keyToFind#)</b>");
if (structKeyExists(fruitStruct, keyToFind)) {
    favoriteFruit = structFind(fruitStruct, keyToFind); // return value of key
    writeOutput(" & <b>structFind(fruitStruct, #keyToFind#)</b><br>")
		writeOutput("Key '#keyToFind#' exists! The value is: " & favoriteFruit & "<br>");
}
else{
  writeOutput(" & <b>structFind(fruitStruct, #keyToFind#)</b><br>");
	writeOutput("Key '#keyToFInd#' does NOT exist! The value is: " & favoriteFruit & "<br>");
}

// 4. structDelete - Remove key from Struct
deleteKeyW = structDelete(fruitStruct, "W"); // Removes Watermelon from the structure
writeOutput("4a. <b>structDelete(fruitStruct, 'W')</b> - #deleteKeyW# (did exist in Structure)<br>" & serializeJSON(fruitStruct) & "<br>");
// BONUS DISCOVERY: If you tried to delete a Key that did not exist, 
// you need the 3rd parameter "indicateNotExisting" to get an accurate boolean of false.  Strange but true.  Keep your boots laced.
deleteKeyQ = structDelete(fruitStruct, "Q", true);
writeOutput("4b.<b>structDelete(fruitStruct, 'Q')</b> -  Delete Key Q: #deleteKeyQ# (does not exist in Structure)<br>");

// 5. structAppend - Append one structure to another one
// Create a separate copy to show appending without destroying our original fruitStruct
appendFruityMeatStruct = duplicate(fruitStruct);

// Merges meatStruct into appendDemoStruct. 
structAppend(appendFruityMeatStruct, meatStruct, false); // False = will NOT overwrite matching keys (B, C, P)
writeOutput("5. <b>structAppend(fruitStruct, meatStruct, false)</b><br>");
writeOutput("<em>(Nope!  Pork, Beef and Chicken didn't make the cut. A key already existed. Remember: Override = false)</em><br>");
writeOutput(serializeJSON(appendFruityMeatStruct) & "<br>");

// Include any additional information that helps summarizes the above examples
additionalPoints = "<br><hr>
<p>
 <b>Additional Points:</b>
 <ul>
  <li><b>Keys are Not Case-sensitive:</b> This is by default.  It could be you assign new data to an existing key and you don't see it updated.  If you wanted it to -- use the Overwrite flag Luke.  I am your Father.</li>
	<li><b>Nested Structures</b> Yeah, it's possible.  We didn't talk about that here, but yeah.  Nesting can quickly become more challenging.  Don't fear it.  Embrace it.</li>
	<li><b>Structures Under the Hood:</b> Structures may have a count of total items, but you cannot use a formal indexed for loop.  Loops for Structures on the next tutorial.</li>
 </ul>
 </p>";
writeOutput(additionalPoints);

Let me know if I've missed your favorite structure function. Or better yet drop a comment so everyone can learn about a brave/bold structure function from ColdFusion.

MORE INPUT
After you've shot your full mag at this code, go have a look at ColdFusion documentation at Adobe and Foundeo's CFDocs.

Thursday, July 23, 2026

ColdFusion Loops - The 5 Minute Mission

You don't have hours to spend ramping up on ColdFusion.
You need to get in. Get out and deliver. Let's do that.

Copy and paste this into a cffiddle.org session.
Yep. Remember to wrap it with <cfscript> tags. Feel free to thank me in the comments.

// ---------------------------------------------------------------------------------------
// Tutorials with a SMART Mission
// What does that look like?

// SMART: Specific, Measurable, Achievable, Revelant and Time-bound
// S: Loop over strings, lists and arrays
// M: Read and digest within 5 minutes
// A: Anyone new/familiar with programing can use them immediately
// R: Use a data in a common ways anyone will mentally and emotionally connnect with
// T: Read within 3 min, Research more within seconds and Experiment with immediately.
// ---------------------------------------------------------------------------------------

// String is a variable is made up of characters.
missionString = "GROCERIES";

// Lists are strings with a delimiter
fruitList = "Apples,Bananas,Blueberries,Strawberries,Grapes,Oranges,Cantaloupe,Watermelon,Kiwi,Pomegranate";
veggieList = "Spinach,Kale,Broccoli,Cauliflower,Radish,Carrot,Potato,Pepper,Corn,Onion";
meatList = "Chicken,Turkey,Fish,Beef,Pork";

// ColdFusion arrays are variables like a giant wall of shelves. You can keep your stuff there.
fruitArray = ["Apples", "Bananas", "Blueberries", "Strawberries", "Grapes", "Oranges", "Cantaloupe", "Watermelon", "Kiwi", "Pomegranate"];
veggieArray = ["Spinach", "Kale", "Broccoli", "Cauliflower", "Radish", "Carrot", "Potato", "Pepper", "Corn", "Onion"];
meatArray = ["Chicken", "Turkey", "Fish", "Beef", "Pork"];

missionIntroduction = "
    <p><b>ColdFusion Loops</b><br>
    As a CF developer, your variables are your variables. Love them.<br>
    Say it.  They are mine. There are many like them. But these are mine.</p>

    <p><b>MISSION:</b> Operation Groceries. Go help your Mama with these variables.</p>

    <p><b>VITAL DATA</b><br>
    <b>missionString</b> : #missionString# (#len(missionString)# characters in length)<br><br>

    <b>Fruits</b> (#arrayLen(fruitArray)#): #ArrayToList(fruitArray)#<br>
    <b>Veggies</b> (#arrayLen(veggieArray)#): #ArrayToList(veggieArray)#<br>
    <b>Meat</b> (#arrayLen(meatArray)#): #ArrayToList(meatArray)#</p>


    <p><b>NEED TO KNOW</b><br><b>1-Based Indexing:</b> ColdFusion lists start at index 1.<br>
    Yes, they start at 1. What the heck? It's ColdFusion's thing.<br>
    Call it a quirk. Get used to it. Love the number 1 and like it.<br>
    Other languages have their indexes start at 0 like JavaScript, C++, Java or Python.</p>
";
writeOutput(missionIntroduction);

writeOutput("<b>EXAMPLES</b><br>");
// 1. Loop through strings
writeOutput("1. Loop through strings (one character at a time):<br>");
for (i = 1; i <= len(missionString); i++) {
    char = mid(missionString, i, 1); // Get single character from string
    writeOutput(char & " ");
}
writeOutput("<br>"); // outputs: G R O C E R I E S

// 2a: Loop through fruitList with for-in
writeOutput("<p>2a. Loop through Fruit lists (one item at a time) - For-In<br>");
writeOutput("<strong>Fruit List:</strong><br>");
for (item in fruitList) {
    writeOutput(item & "<br>");
}
writeOutput("</p>");  // outputs each fruit on a new line

// 2b: Loop through meatList with index-based for
writeOutput("<p>2b. Loop through Meatlists (one item at a time) - Index-Based for<br>");
writeOutput("<strong>Meat List:</strong><br>");
for (i = 1; i <= listLen(meatList); i++) {
    item = listGetAt(meatList, i);
    writeOutput(i & ": " & item & "<br>");
}
writeOutput("</p>"); // outputs each meat with its index on a new line

// 3a: Loop through veggieArray with for-in
writeOutput("<p>3a. Loop through Veggie arrays (one item at a time) - For-In<br>");
writeOutput("<strong>Veggie Array:</strong><br>");
for (item in veggieArray) {
    writeOutput(item & "<br>");
}
writeOutput("</p>");  // outputs each veggie on a new line

// 3b: Loop through fruitArray with index-based for
writeOutput("<p>3b. Loop through fruitArray (one item at a time) - Index-based for:<br>");
writeOutput("<strong>Fruit Array:</strong><br>");
for (i = 1; i <= arrayLen(fruitArray); i++) {
    writeOutput(i & ": " & fruitArray[i] & "<br>");
}
writeOutput("</p>"); // outputs each fruit with its index on a new line

// Include any additional information that helps summarizes the above examples
additionalPoints = "<br><hr>
<p>
 <strong>Additional Points:</strong>
 <ul>
  <li><b>Loops Under the Hood:</b> Loops can start any where but if you loop through strings, lists and arrays they start at 1.  Yep!  Index-based at 1.</li>
  <li><b>Empty Lists or Arrays:</b> It happens. If a list or array has no items, it won't enter the loop.  It won't do jack-squat.  There's nothing to loop over.  Keep that in mind.</li>
  <li><b>Looping Over Structs:</b> We haven't talked about those yet.  They are the grub, you've been waiting for bub.  You need those.  But that's a whole other tutorial.</li>
 </ul>
 </p>";
writeOutput(additionalPoints);

Let me know if I've missed your favorite loop. Or better yet point me to another site where everyone can learn about a loop from ColdFusion.

MORE INPUT
After your done with your morning run at this code, go have a look at ColdFusion documentation at Adobe and Foundeo's CFDocs.

Wednesday, July 22, 2026

ColdFusion Array Functions - The 5 Minute Mission

You don't have hours to spend ramping up on ColdFusion.
You need to get in. Get out and deliver. Let's do that.

Copy and paste this into a cffiddle.org session.
Yep. Remember to wrap it with <cfscript> tags. Feel free to thank me in the comments.

// ---------------------------------------------------------------------------------------
// Tutorials with a SMART Mission
// What does that look like?

// SMART: Specific, Measurable, Achievable, Revelant and Time-bound
// S: Array Functions
// M: Read and digest within 5 minutes
// A: Anyone new/familiar with programing can use them immediately
// R: Use a data in a common ways anyone will mentally and emotionally connnect with
// T: Read within 3 min, Research more within seconds and Experiment with immediately.
// ---------------------------------------------------------------------------------------

// ColdFusion arrays are variables like a giant wall of shelves. You can keep your stuff there.
fruitArray = ["Apples", "Bananas", "Blueberries", "Strawberries", "Grapes", "Oranges", "Cantaloupe", "Watermelon", "Kiwi", "Pomegranate"];
veggieArray = ["Spinach", "Kale", "Broccoli", "Cauliflower", "Radish", "Carrot", "Potato", "Pepper", "Corn", "Onion"];
meatArray = ["Chicken", "Turkey", "Fish", "Beef", "Pork"];

missionIntroduction = "
    <p><b>ColdFusion Array Functions</b><br>
    As a CF developer, you use these on a daily basis. Pick these up. You gonna need all 11 of 'em.</p>

    <p><b>MISSION:</b> Operation Groceries. Go help your Mama with these three arrays.</p>

    <p><b>VITAL DATA</b><br>
    <b>Fruits</b> (#arrayLen(fruitArray)#): #ArrayToList(fruitArray)#<br>
    <b>Veggies</b> (#arrayLen(veggieArray)#): #ArrayToList(veggieArray)#<br>
    <b>Meat</b> (#arrayLen(meatArray)#): #ArrayToList(meatArray)#</p>

    <p><b>NEED TO KNOW</b><br><b>1-Based Indexing:</b> ColdFusion lists start at index 1.<br>
    Yes, they start at 1. What the heck? It's ColdFusion's thing.<br>
    Call it a quirk. Get used to it. Love the number 1 and like it.<br>
    Other languages have their indexes start at 0 like JavaScript, C++, Java or Python.</p>
";
writeOutput(missionIntroduction);

writeOutput("<b>EXAMPLES</b><br>");
// 1. arrayLen - Count items in fruit Array
totalFruits = arrayLen(fruitArray);
writeOutput("1. arrayLen(fruitArray) - Total fruits: #totalFruits#<br>");
// Output: 10

// 2. arrayAppend - add to end
ArrayAppend(fruitArray, "Mango");
WriteOutput("2. arrayAppend(fruitArray, 'Mango') - " & ArrayToList(fruitArray) & "<br>");
// ["Apples", "Bananas", "Blueberries", "Strawberries", "Grapes", "Oranges", "Cantaloupe", "Watermelon", "Kiwi", "Pomegranate", "Mango"]

// 2. arrayPrepend: add to start
ArrayPrepend(veggieArray, "Garlic");
WriteOutput("3. arrayPrepend(veggieArray, 'Garlic') - " & ArrayToList(veggieArray) & "<br>");
// ["Garlic", "Spinach", "Kale", "Broccoli", "Cauliflower", "Radish", "Carrot", "Potato", "Pepper", "Corn", "Onion"]

// 4. arrayInsertAt: Insert at specific index (shifts others down)
ArrayInsertAt(meatArray, 2, "Lamb"); // Insert "Lamb" at index 2 in meatArray
WriteOutput("4. arrayInsertAt(meatArray, 2, 'Lamb') - " & ArrayToList(meatArray) & "<br>");
// ["Chicken", "Lamb", "Turkey", "Fish", "Beef", "Pork"]

// 5. arrayDeleteAt: Remove item at index 5 (Grapes)
ArrayDeleteAt(fruitArray, 5);
WriteOutput("5. ArrayDeleteAt(fruitArray, 5) - " & ArrayToList(fruitArray) & "<br>");
// ["Apples", "Bananas", "Blueberries", "Strawberries", "Grapes", "Oranges", "Cantaloupe", "Watermelon", "Kiwi", "Pomegranate", "Mango"]

// 6. arrayFind: Case-sensitive (returns index or 0 if not found)
pos = ArrayFind(fruitArray, "kiwi"); 
WriteOutput("6. ArrayFind(fruitArray, 'kiwi') - " & pos & " (0 = not found)<br>");
// Expected: 0 (not found)

// 7. arrayFindNoCase: Case-insensitive search (returns index or 0 if not found)
posNoCase = ArrayFindNoCase(fruitArray, "kiwi");
WriteOutput("7. arrayFindNoCase(fruitArray, 'kiwi') - " & posNoCase & " (9 = found)<br>");
// Expected: 9 (or current index)

// 8. arrayContains: Returns Boolean if array contains value
hasBroccoli = ArrayContains(veggieArray, "Broccoli");
WriteOutput("8a. arrayContains(veggieArray, 'Broccoli') - " & hasBroccoli & "<br>");
// Expected: true

hasRice = ArrayContains(veggieArray, "Rice");
WriteOutput("8b. arrayContains(veggieArray, 'Rice') - " & hasRice & "<br>");
// Expected: false

// 9. arraySlice: Extract subset (Start Index, Length)
firstThreeVeggies = ArraySlice(veggieArray, 1, 3);
WriteOutput("9. arraySlice(veggieArray, 1, 3) - " & ArrayToList(firstThreeVeggies) & "<br>");
// Expected: Garlic, Spinach, Kale

// 10. ArrayToList: Convert to string
meatCSV = ArrayToList(meatArray);
WriteOutput("10. arrayToList(meatArray) - " & meatCSV & "<br>");
// Output: Chicken,Lamb,Turkey,Fish,Beef,Pork

// ArrayToList with custom delimiter
fruitPipe = ArrayToList(fruitArray, "|");
WriteOutput("11. arrayToList(fruitArray, '|') - " & fruitPipe & "<br>");
// Output: Apples|Bananas|Blueberries|Strawberries|Oranges|Cantaloupe|Watermelon|Kiwi|Pomegranate|Mango

// Include any additional information that helps summarizes the above examples
additionalPoints = "<br><hr>
<p>
 <strong>Additional Points:</strong>
 <ul>
  <li><b>Arrays Under the Hood:</b> ArrayAppend alters the original variable; yeah, it's cool. Keep the change.</li>
  <li><b>Find vs. Contains:</b> ArrayFind expects an exact match of the whole list item, but ArrayContains matches partial substrings inside an item.  They search differently.  Shove that in your cargo pant pocket.</li>
 </ul>
 </p>";
writeOutput(additionalPoints);

Let me know if I've missed your favorite array function. Or better yet point me to another site where everyone can learn about a hearty array function from ColdFusion.

MORE INPUT
After you've shot your full mag at this code, go have a look at ColdFusion documentation at Adobe and Foundeo's CFDocs.

Monday, July 20, 2026

ColdFusion String Functions - The 5 Minute Mission

You don't have hours to spend ramping up on ColdFusion.
You need to get in. Get out and deliver. Let's do that.

Copy and paste this into a cffiddle.org session.
Yep. Remember to wrap it with <cfscript> tags. Feel free to thank me in the comments.

// ---------------------------------------------------------------------------------------
// Tutorials with a SMART Mission
// What does that look like?
// 
// SMART: Specific, Measurable, Achievable, Revelant and Time-bound
// S: String Functions
// M: Read and digest within 5 minutes
// A: Anyone new/familiar with programing can use them immediately
// R: Use a data in a common ways anyone will mentally and emotionally connnect with
// T: Read within 3 min, Research more within seconds and Experiment with immediately.
// ---------------------------------------------------------------------------------------

// ColdFusion strings are variables made up of characters (letters, numbers, etc.)

// 1. Define the initial data sets
fruitList  = "Apples,Bananas,Blueberries,Strawberries,Grapes,Oranges,Cantaloupe,Watermelon,Kiwi,Pomegranate";
veggieList = "Spinach,Kale,Broccoli,Cauliflower,Radish,Carrot,Potato,Pepper,Corn,Onion";
meatList   = "Chicken,Turkey,Fish,Beef,Pork";

missionIntroduction = "
    <p><b>ColdFusion String Functions</b><br>
    As a CF developer, you use these often. Pick these up. You gonna need all 11 of 'em.</p>

    <p><b>MISSION:</b> Operation Groceries. Go help your Mama because she's a remarkable lady.</p>

    <p><b>VITAL DATA</b><br>
    <b>Fruits</b> (#listLen(fruitList)#): #fruitList#<br>
    <b>Veggies</b> (#listLen(veggieList)#): #veggieList#<br>
    <b>Meat</b> (#listLen(meatList)#): #meatList#</p>

    <p><b>NEED TO KNOW</b><br><b>1-Based Indexing:</b> ColdFusion strings start at index 1.<br>
    Yes, they start at 1. What the heck? It's ColdFusion's thing.<br>
    Call it a quirk. Get used to it. Love the number 1 and like it.<br>
    Other languages have their indexes start at 0 like JavaScript, C++, Java or Python.</p>
";
writeOutput(missionIntroduction);

writeOutput("<b>EXAMPLES</b><br>");

// 1. Execute String Length
lenResult = Len(meatList); 
writeOutput("1. Len(meatList) - #lenResult#  (that's characters to you, soldier)<br><br>");

// 2. Trim string of leading and trailing spaces
paddedMeat  = "  " & meatList & "  ";
writeOutput("<em>paddedMeat has spaces:</em> '#paddedMeat#'<br>");
trimResult  = Trim(paddedMeat); 
writeOutput("2.Trim(paddedMeat) - '#trimResult#' (trimmed leading/trailing spaces)<br><br>");

// 3. Execute conversion to Uppercase and Lowercase
ucResult = UCase(meatList);
writeOutput("3a. UCase(meatList) - #ucResult#<br>");

lcResult = LCase(veggieList); 
writeOutput("3b. LCase(veggieList) - #lcResult#<br><br>");

// 4. Execute extraction of substrings
leftResult = Left(fruitList, 6); // Apple 
writeOutput("4a. Left(fruitList, 6) - #leftResult#<br>");

rightResult = Right(veggieList, 5); // Onion
writeOutput("4b. Right(veggieList, 5) - #rightResult#<br>");

midResult = Mid(meatList, 9, 6);  // Turkey
writeOutput("4c. Mid(meatList, 9, 6) - #midResult#<br><br>");


// 5. Execute Finding and Searching (1-based index results. Found = index, Not Found = 0)
// Case-sensitive search...
findFailResult = Find("beef", meatList); 
writeOutput("5a. Find('beef') - #findFailResult# (not found; case-sensitive search)<br>");

findResult = Find("Beef", meatList);
writeOutput("5b. Find('Beef') - #findResult# (found at index 21; case-sensitive search) <br>");

// Non-case-sensitive search...
findNoCaseResult = FindNoCase("beef", meatList);
// IMHO: Everyone should always capitalize Beef anyway, because it's the best meat on the planet.
writeOutput("5c. FindNoCase('beef') - #findNoCaseResult# (found at index 21 - NOT case-sensitive) <br><br>");

// 6. Execute String Modifications (Insert uses 0-based index)
replaceResult = Replace(fruitList, "Strawberries", "Blackberries"); 
writeOutput("6a. Replace(fruitList, 'Strawberries', 'Blackberries')<br> #replaceResult#<br>");
insertResult = Insert("Lamb,", meatList, 8); 
writeOutput("6b. Insert('Lamb,' meatList, 8) - #insertResult#<br>");

// Include any additional information that helps summarizes the above examples
additionalPoints = "<br><hr>
<p>
 <strong>Additional Points:</strong>
 <ul>
  <li><b>Strings Under the Hood:</b> Long strings can impact on performance.  Keep 'em short.  Too long? Then look into Arrays.</li>
  <li><b>Insert, but no Remove:</b> Correct.  If you want remove a chunk of a string you would use replace.</li>
  <li><b>Missed GetToken:</b> Good catch!  I did that on purpose.  That will be discussed in the next post on Arrays.</li>
 </ul>
 </p>";
writeOutput(additionalPoints);

MORE INPUT
After you've bench pressed this code, go have a look at ColdFusion documentation at Adobe and Foundeo's CFDocs. Then read about the string performance article by Brad Wood Confessions of a Speed Junky: How I made my code faster.

Tuesday, July 14, 2026

List Functions Game - Guess What is Missing

You need to use the List Functions from our last post. Here's a game.

Tweak it. Devour it. Then write your own.

Copy and paste this into a cffiddle.org session.
Yep. Remember to wrap it with <cfscript> tags. Feel free to thank me later.


// ---------------------------------------------------------------------------------------
// GAME with a SMART Mission
// What does that look like?
//
// SMART: Specific, Measurable, Achievable, Revelant and Time-bound
// S: List Functions - Guess What is Missing from the List
// M: Read and digest within 5 minutes
// A: Anyone new/familiar with programing can use them immediately
// R: Use a data in a common ways anyone will mentally and emotionally connnect with
// T: Read within 3 min, Research more within seconds and Experiment with immediately.
// ---------------------------------------------------------------------------------------
// FUNCTIONS USED:
//  List: listLen, listGetAt, listDeleteAt
//  String: trim
// ---------------------------------------------------------------------------------------

// Add a CSS class to render the "Answer" to the bottom of the page
// ** This isn't a best practice, soldier.  
// ** Be a pro, put styles in an external stylesheet.
writeOutput("<style>.pushDownLower { margin-top: 22em; }</style>");

// Initialize the list.  You need your protein and it better be free-range and grass-fed.
originalList = "Beef, Chicken, Fish, Lamb, Pork, Turkey";

listLength = originalList.listLen();

// Pick a random index to delete (between 1 and total items)
randomIndex = RandRange(1, listLength);

// Get the exact item being removed for the game log
removedItem = originalList.listGetAt(randomIndex);

// Remove the random item from the list
updatedList = originalList.listDeleteAt(randomIndex);

// You'll need a humorous retort later.
// No one likes stuff taken away from them.
snappyComeBackArray = [
 "Moo! Moo! I like my shoes.  Give them back.",
 "I like my BBQ with sweet potatoes and deep-fried.",
 "Fresh sushi is calling my name, even now.",
 "Get in my belly with caramelized onions.",
 "Everything goes better with bacon.",
 "Oh how thankful I am.  I am."
];

// Capture the output inside a variable using savecontent
savecontent variable="gameOutput" {
  writeOutput("
    <h2>Guess What is Missing...</h2>
    <p><b>Original:</b> #originalList# (#listLength# items)</p>
    <p><b>Updated:</b> #updatedList#</p>
    <p class='pushDownLower'><hr>Randomly removed item <em>#randomIndex# (#removedItem.trim()#)...</em></p>
    <h1>#snappyComeBackArray[randomIndex]#</h1>
  ");
}

// Display the captured content to the screen
writeOutput(gameOutput);

If you have another game in mind, let me know in the comments.