Selecting The Seven Languages In Seven Weeks Winners

Posted February 10, 2011 at 10:14 AM by Ben Nadel

Tags: ColdFusion

About a week or so ago, I finished working my way through Seven Languages in Seven Weeks by Bruce Tate. To celebrate my mostly triumphant reading of the book (shakes fist at Haskell, Day 3), I wanted to give away a few copies. But, in order to select the winners of the book, I wanted to have a little fun and try to play with the Mapping concepts that were often discussed within the book.

Given an array of players (those that submitted sample code on my wrap-up), I created an ArrayMap() function and a function that would randomly return a given value. The idea was to continue to reduce the collection of players until only 2 were left.

  • <!--- Set up the array of players. --->
  • <cfset players = [
  • "Wilkins",
  • "Mike",
  • "Seth Stone",
  • "Guganeshan.T",
  • "Joshua Caito",
  • "Joe Zack",
  • "Andrew",
  • "Rich",
  • "Hidde-Jan",
  • "dotnetCarpenter",
  • "Adam Coffman",
  • "Owen Pellegrin",
  • "Ross Pfahler",
  • "Marty",
  • "Jared Cacurak",
  • "Morten",
  • "Greg Mefford",
  • "Tracy Harms",
  • "Eric Mitchell",
  • "Jesse Riggins",
  • "Danny Philayvanh",
  • "Sharagoz",
  • "Joel Neley",
  • "Adam",
  • "Nelle",
  • "Matt Gutting",
  • "Cade Cannon"
  • ] />
  •  
  •  
  • <!--- ----------------------------------------------------- --->
  • <!--- ----------------------------------------------------- --->
  •  
  •  
  • <!---
  • Define a map function that maps one array onto another using
  • the given function. When mapping, the following values will be
  • handles as such:
  •  
  • - Array - will be flattened and merged into the resultant array.
  • - Value - will be added to the resultant array.
  • - VOID - will not be added ot the resultant array.
  • --->
  • <cffunction
  • name="arrayMap"
  • access="public"
  • returntype="array"
  • output="false"
  • hint="I map one array onto another array.">
  •  
  • <!--- Define arguments. --->
  • <cfargument
  • name="originalArray"
  • type="array"
  • required="true"
  • hint="I am the array being mapped."
  • />
  •  
  • <cfargument
  • name="mapper"
  • type="any"
  • required="true"
  • hint="I am the function used to perform the mapping."
  • />
  •  
  • <!--- Define the local scope. --->
  • <cfset var local = {} />
  •  
  • <!--- Define an array to hold the results of the mapping. --->
  • <cfset local.results = [] />
  •  
  • <!--- Loop over the array so we can map each value. --->
  • <cfloop
  • index="local.originalValue"
  • array="#arguments.originalArray#">
  •  
  • <!--- Hand this value off to the mapper function. --->
  • <cfset local.mappedValue = arguments.mapper(
  • local.originalValue
  • ) />
  •  
  • <!---
  • Check to make sure that a value exists. If it doesn't,
  • it means that VOID was returned; as such, no mapped
  • value will be added to the results.
  • --->
  • <cfif structKeyExists( local, "mappedValue" )>
  •  
  • <!---
  • We know we have a mapped value, so let's not figure
  • out how we are merging it into the results array.
  • Arrays will be flattened; single values will be
  • added as such.
  • --->
  • <cfif isArray( local.mappedValue )>
  •  
  • <!--- Add each value of the array individually. --->
  • <cfloop
  • index="local.mappedSubValue"
  • array="#local.mappedValue#">
  •  
  • <!--- Add the flattened values. --->
  • <cfset arrayAppend(
  • local.results,
  • local.mappedSubValue
  • ) />
  •  
  • </cfloop>
  •  
  • <cfelse>
  •  
  • <!--- Simply add the returned value. --->
  • <cfset arrayAppend(
  • local.results,
  • local.mappedValue
  • ) />
  •  
  • </cfif>
  •  
  • </cfif>
  •  
  • </cfloop>
  •  
  • <!--- Return the resultant array. --->
  • <cfreturn local.results />
  • </cffunction>
  •  
  •  
  • <!--- ----------------------------------------------------- --->
  • <!--- ----------------------------------------------------- --->
  •  
  •  
  • <!---
  • Now that we have our map function defined, we need to create a
  • function that actually provides the mapping logic. For our
  • purposes, we're going to keep mapping the players array onto a
  • new array until we only have 2 people left. That means that our
  • mapper function will be popping people out of the collection.
  • --->
  • <cffunction
  • name="returnRandom"
  • access="public"
  • returntype="any"
  • output="false"
  • hint="I randomly return the given value or VOID.">
  •  
  • <!--- Define arguments. --->
  • <cfargument
  • name="value"
  • type="any"
  • required="true"
  • hint="I am the value being returned (maybe!)."
  • />
  •  
  • <!---
  • Randomly decide to return this value or not. If it is
  • returned, it will be mapped onto the results array; if it
  • is not, it will be removed.
  • --->
  • <cfif (rand() gt .25)>
  •  
  • <!--- Return the given value. --->
  • <cfreturn arguments.value />
  •  
  • <cfelse>
  •  
  • <!--- Return void. --->
  • <cfreturn />
  •  
  • </cfif>
  • </cffunction>
  •  
  •  
  • <!--- ----------------------------------------------------- --->
  • <!--- ----------------------------------------------------- --->
  •  
  •  
  • <!---
  • Now that we have all of our mapping functions in place, let's
  • reduce our players collection down to a collection of 2. As we
  • map, there is a chance that we will drop below 2. In that case,
  • we'll have to just start over again.
  • --->
  • <cfoutput>
  •  
  •  
  • <!---
  • Keep looping until we stop. If we get a collection of 2,
  • we will execute an explicit Break command.
  • --->
  • <cfloop condition="true">
  •  
  • <!--- Copy our players array (set by VALUE). --->
  • <cfset winners = players />
  •  
  •  
  • <!--- Output the staring length. --->
  • Starting Length: #arrayLen( winners )#<br />
  •  
  •  
  • <!---
  • Keep reducing the collection until it is less than
  • or equal to 2 (we are hoping it is 2).
  • --->
  • <cfloop condition="(arrayLen( winners ) gt 2)">
  •  
  • <!--- Reduce the collection randomly. --->
  • <cfset winners = arrayMap(
  • winners,
  • returnRandom
  • ) />
  •  
  • <!--- Output the new length. --->
  • Current Length: #arrayLen( winners )#<br />
  •  
  • </cfloop>
  •  
  •  
  • <!--- Check to see if the collection contains 2 values. --->
  • <cfif (arrayLen( winners ) eq 2)>
  •  
  • <!---
  • We have reduced properly. Stop the reduction loop
  • as we have found our winners.
  • --->
  • <cfbreak />
  •  
  • </cfif>
  •  
  • </cfloop>
  •  
  •  
  • <hr />
  •  
  • <!--- Output the winners. --->
  • Winner: #winners[ 1 ]#<br />
  • Winner: #winners[ 2 ]#<br />
  •  
  • </cfoutput>

Since the reduction mapping might result in an array of length less than 2, I had to continually loop until the final array contained exactly two elements. When I ran the above code, I got the following page output:

Starting Length: 27
Current Length: 18
Current Length: 15
Current Length: 13
Current Length: 11
Current Length: 11
Current Length: 5
Current Length: 3
Current Length: 3
Current Length: 1
Starting Length: 27
Current Length: 21
Current Length: 16
Current Length: 10
Current Length: 8
Current Length: 8
Current Length: 7
Current Length: 7
Current Length: 7
Current Length: 5
Current Length: 1
Starting Length: 27
Current Length: 22
Current Length: 21
Current Length: 13
Current Length: 10
Current Length: 6
Current Length: 6
Current Length: 5
Current Length: 5
Current Length: 3
Current Length: 3
Current Length: 2
-------------------------------------------------
Winner: Jared Cacurak
Winner: Matt Gutting

As you can see, the reduction mapping had to run 3 times before it ended up with an array of length 2. Of course, I know there are much more efficient ways of doing this; but, efficiency wasn't really the point - I just wanted to have some fun with it.

Congratulations to Jared and Matt! You're about to get seven languages deep!



Reader Comments

Feb 10, 2011 at 10:45 AM // reply »
13 Comments

Stupid ColdFusion!
I thought the point of your blog was to make me like ColdFusion, now I am not so sure it will every happen :)

/A Loser


Feb 10, 2011 at 10:51 AM // reply »
11,241 Comments

@Morten,

Ha ha ha, the silver-lining to all of this is that if you use ColdFusion, you're already a winner :P


Feb 10, 2011 at 10:57 AM // reply »
4 Comments

Feels good to see the name 'inside' coldfusion code ^_^

Congrats to winners.


Feb 10, 2011 at 11:06 AM // reply »
11,241 Comments

@Guganeshan,

Thanks for participating my friend :)


Feb 10, 2011 at 12:09 PM // reply »
3 Comments

Grats to the winners!

Thanks again for your creativity with the contest Ben. It would be cool to do something like this every once in a while even if there is no prize involved :)


Feb 10, 2011 at 2:38 PM // reply »
11,241 Comments

@Andrew,

Always a pleasure to get smart people involved in good conversation :)


Feb 11, 2011 at 4:34 PM // reply »
211 Comments

@Ben: Your mom is very informative. Thanks.

;)


Feb 11, 2011 at 4:41 PM // reply »
11,241 Comments

@Todd,

Ha ha ha, well played :)


Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
May 22, 2013 at 7:52 AM
Nested Views, Routing, And Deep Linking With AngularJS
Hi, Just a quick thank you. As it happens, for my own purposes, the pending ui-router work being done in native angular is likely the one I'll adopt, but your exploration, code and documentation of ... read »
May 22, 2013 at 4:43 AM
How Do You Use The ColdFusion CFParam Tag?
'<cfparam>' or 'isDefined()and <cfset>' performs the same task.Is there any difference? ... read »
May 21, 2013 at 7:46 PM
Using Plupload For Drag & Drop File Uploads In ColdFusion
No luck. At least I have uncovered the cause, URLScan 3.1. Here is what I see in the IIS log when a file is over 30mb. 2013-05-21 23:29:05 10.105.45.128 GET /plupload/assets/jquery/jquery-1.8. ... read »
May 21, 2013 at 6:12 PM
Using Plupload For Drag & Drop File Uploads In ColdFusion
Ben, I did not see you after Pete Freitag's Lockdown session at cfObjective but he said that IIS sets file size limits at 30MB by default which just happened to be the threshold for file size when ... read »
May 21, 2013 at 11:51 AM
Ask Ben: Parsing Very Large XML Documents In ColdFusion
Looking at my first ever XML document that I have to parse and put into MS SQL 2000 with CF8. I get it to list the desired Field name, many times over, and have a long list of this field name displa ... read »
May 21, 2013 at 9:25 AM
Turning Off and On Identity Column in SQL Server
you are awesome..i am lucky to get this blog between such a garbage one....Thanks, Prashant ... read »
May 20, 2013 at 4:38 PM
Using A Dynamic Column Name With ValueList() In ColdFusion
@Dana, Your confusion is well founded, since this is a very confusing features. In fact, it ONLY works if you use array notation. Meaning, that this: arrayToList( query[ "columnName" ] ) ... read »
May 20, 2013 at 4:34 PM
Using A Dynamic Column Name With ValueList() In ColdFusion
I was thinking chicken and the egg, I wouldn't have expected it to work in the valuelist going in I guess. Maybe I just need a beer, long day :) ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools