Blog

Eric Peterson

December 20, 2017

Spread the word


Share your thoughts

Welcome to day 7. We're over half way through! I hope you've enjoyed learning about a few of these awesome modules on ForgeBox. Want to say thanks for some of these modules? Make sure to star the repos on GitHub!

Now, on to today's module: cfcollection.

cfcollection

Functional Programming

Functional programming can make your code more expressive. Take these two examples:

var newUsers = [];
for ( var user in oldUsers ) {
    arrayAppend( newUsers, user.username );
}
return newUsers;

This is pretty succienct code, but you have to read it all to know what it is doing. It is transforming an array of users in to an array of usernames.

Now, take a look at the map equivalent:

return collect( users ).map( function( user ) {
    return user.username;
} ).get();

The biggest benefit here is that map has semantics where a for loop does not. When you see map, you know you are getting an array back the same length as the source array with every item transformed in some way. With a for loop, you just have to read the loop to figure out what it is doing.

With cfcollection, this can be taken further into an even higher level function:

return collect( users ).pluck( "username" ).get();

pluck has further semantics of being a map that returns a property off of the objects passed in. These semantics keep your code clean and make chaining methods a more expressive way to program. cfcollection includes many of these expressive, chainable methods to help make reading your code flow.

Futher semantic methods can clean your code up even more:

return collect( users )
    .filter( function( user ) {
        return user.isActive;
    } )
    .reduce( function( total, user ) {
        return total + user.salary;
    }, 0 );
return collect( users )
    .where( "isActive", true )
    .sum( "salary" );

A quick note about performance. A concern many people have when getting in to a more functional pipeline style of programming as seen here is that we are now looping multiple times over the same collection instead of one time with a for loop. That is true, but in most cases it doesn't matter. The time added to loop over your collection multiple times most likely pales in comparison to, for exampe, your database queries. The right approach is to focus on correct, clean code first. Then measure and fix where the measurements tell you to. Don't just fix where you think the problem is. Remember: make it work, make it right, make it fast.

Member Functions Everywhere!

This section could also have been labelled CFEngine compatibility. cfcollection is tested on Adobe ColdFusion (ACF) 10, 11, and 2016 as well as Lucee 4 and 5. This means that even if you are on ACF 10 and don't have member functions or need to support multiple engines (like a module!) you can have them through cfcollection.

Mixins

Mixins are a super neat feature of cfcollection powered by WireBox! Any component managed through WireBox can have a any number of files mixed in when creating an instance of the component. This lets you extend components with arbitrary functionality. Take this example:

// config/ColdBox.cfc
moduleSettings = {
    cfcollection = {
        mixinLocations = "/app/includes/macros/CFCollectionMacros"
    }
};


function triple() {
    return this.map( function( item ) {
        return item * 3;
    } );
}

// handlers/main.cfc

property name="collect" inject="collect@CFCollection";

function index( event, rc, prc ) {
    var nums = collect( [ 1, 2, 3, 4, 5 ] );
    event.renderData( nums.triple().get() );
    // [ 3, 6, 9, 12, 15 ]
}

The biggest benefit here is that you don't need every collection method added to the cfcollection core. You can add your own pipeline functions directly in to your collections. Whether this is your favorite utility that's not in the core, or a utility specific to a project, this lets you stay in the expressive, functional pipeline world no matter what your use case.

Wrap Up

cfcollection is basically an automatic install in all my CFML projects now a days. The consistent member functions, the expressive pipelines, and the ability to mix my own methods in make it invaluable for keeping my code readable and clean.

Add Your Comment

Recent Entries

Into the Box Sessions Round 2 and Team Packs!

Into the Box Sessions Round 2 and Team Packs!

The second round of Into the Box sessions is here, packed with incredible new topics, sessions and expert speakers industry leaders in modern CFML getting us modern content and practices you can use to make your coding experience and projects better, faster and easy and expert-led talks on modern web development, serverless applications, cryptography, UI design, and more.

Maria Jose Herrera
Maria Jose Herrera
February 25, 2025
Building Serverless Functions with BoxLang in AWS Lambda!

Building Serverless Functions with BoxLang in AWS Lambda!

The serverless computing model has revolutionized the way we deploy and manage applications, and with BoxLang, it’s easier than ever to leverage AWS Lambda for efficient, scalable execution of cloud functions. In a recent blog post, Ray Camden explored the process of building and deploying BoxLang functions in AWS Lambda. Let’s take a closer look at how it works!

Maria Jose Herrera
Maria Jose Herrera
February 24, 2025
ColdBox Training: From Hero to Superhero – Master ColdFusion and BoxLang Development

ColdBox Training: From Hero to Superhero – Master ColdFusion and BoxLang Development

Are you ready to take your ColdBox development skills for ColdFusion and BoxLang to the next level? Whether you're new to ColdBox or looking to sharpen your expertise, our ColdBox From Hero to Superhero training is the perfect opportunity to become a ColdFusion and BoxLang powerhouse.

Why Attend?

This hands-on training is designed to help ColdFusion and BoxLang developers level up their ...

Cristobal Escobar
Cristobal Escobar
February 19, 2025