Create a list in a loop - coldfusion

I am trying to create a comma separated list inside a loop, but I think I am missing something. When I dump item_id_list, I just get items separated by a space - not a comma. Can anyone point what am I missing?
<cfloop array="data" index="doc">
<cfif structKeyExists(doc, "id") >
<cfset the_item_id = doc.id />
</cfif>
<cfset item_id_list = ''/>
<cfset item_id_list = listappend(item_id_list,'#the_item_id#',',')/>
</cfloop>

Create the list outside of the loop:
<cfset item_id_list = "" />
<cfloop array="#data#" index="doc">
<cfif structKeyExists(doc, "id") >
<cfset item_id_list = listappend(item_id_list, doc.id, ",") />
</cfif>
</cfloop>

Will this work?
<cfset item_id_list = ArrayToList(data.id)>
EDIT: Oops. Can't reference a struct in an array like that. Instead try:
<cfscript>
item_id_list = "" ;
for (row in data) {
if (structkeyexists(row,"id") ) {
item_id_list = listappend(item_id_list,row.id) ;
}
}
</cfscript>
For loops like this, cfscript syntax is easier to see.

Related

ColdFusion locale specific currency inputs in forms using commas (ie french Canadian 2 222,22$)

Is there an easier/shorter way to convert the final comma of a currency input to a decimal.
Inputs look like 2 000,99 OR 2,000,99
MySQL wants them to look like 2000.99
<cfform action="commatest.cfm?gotime" onsubmit="commatest.cfm" method="post" name="waiv">
<cfinput type="text" name="commer">
<input type="submit" style="width:180px;" value="convertme" class="hide button">
</cfform>
<cfif isdefined("gotime")>
<!--- START SCRIPT --->
<cfset formentry = FORM.commer>
<cfset howlong = #len(formentry)#>
<cfif howlong GT 3>
<cfset leftlen = howlong - 3>
<cfset rside = #right(formentry, 3)#>
<cfset rside = ReReplace(rside,"[,]",".", "ALL")>
<cfset lside = #left(FORM.commer, leftlen)#>
<cfset lside = ReReplaceNoCase(lside,"[-$A-Z,]","", "ALL")>
<cfset lside = reReplace(lside, "[[:space:]]", "", "ALL") />
<cfset newb = #lside# & #rside#>
<!--- OUTPUT TO DATABASE (or webpage in this case) --->
<cfoutput>
<h1>#newb# (number? #IsNumeric(newb)#)</h1>
</cfoutput>
<cfelse>
<cfoutput>
<h1>#formentry# (number? #IsNumeric(formentry)#)</h1>
</cfoutput>
</cfif>
</cfif>
As usual there are several different ways to do this. I would probably do something like this:
<cfscript>
source1 = '2 000,99';
source2 = '2,000,99';
// remove ALL commas and spaces
example1 = REReplace(source1,"[\s,]","","all");
example2 = REReplace(source2,"[\s,]","","all");
// insert a decimal before the last two digits
example1 = Insert(".",example1,(Len(example1)-2));
example2 = Insert(".",example2,(Len(example2)-2));
writeOutput(source1 & " = " & example1);
writeOutput("<br>");
writeOutput(source2 & " = " & example2);
</cfscript>
That code gives the following output:
2 000,99 = 2000.99
2,000,99 = 2000.99
Of course this assumes that the last two digits are always going to be after the decimal point.
Here is a gist of the code above.

Any better way to loop through a collection (struct) in CFML?

Please have a look at the code block below:
<cfset index = 0 />
<cfloop collection="#anotherPerson#" item="key" >
<cfset index = index+1 />
<cfoutput>
#key# : #anotherPerson[key]#
<cfif index lt ArrayLen(structKeyArray(anotherPerson))> , </cfif>
</cfoutput>
</cfloop>
<!--- Result
age : 24 , haar : Blondes haar , sex : female , ort : Hanau
---->
Now can you please tell me how could I achieve the same result without setting an index outside and incrementing it inside the loop? If you notice carefully, I had to write two more cfset tag and one cfif tag with expensive code just to avoid a comma (,) at the end of the collection!
Ok, I'm showing you two answers. The first will run on ColdFusion 9. Since other people might find this thread and be using Lucee Server or a newer version of Adobe ColdFusion, I'm including a one-liner that uses higher order functions and runs on ACF 2016. There's a lot of syntactic sugar (like member functions) and functional programming you're missing by being on CF9. These answers use script, because manipulating data is not something for a view (where tags/templating are used).
Set up the data
myStruct = { 'age'=24, 'haar'='Blondes haar', 'sex'='female', 'ort'='Hanau' };
CF9 compat, convert data to array and use delimiter to add commas
myArray = [];
for( key in myStruct ) {
arrayAppend( myArray, key & ' : ' & myStruct[ key ] );
}
writeOutput( arrayToList( myArray, ', ' ) );
Modern CFML. Use struct reduction closure to convert each key into an aggregated array which is then turned into a list.
writeOutput( myStruct.reduce( function(r,k,v,s){ return r.append( k & ' : ' & s[ k ] ); }, [] ).toList( ', ' ) );
http://cfdocs.org/structreduce
Some friends provided two different solutions. Both are efficient and elegant!
Solution 1
<cfset isFirst = true />
<cfloop collection="#anotherPerson#" item="key" >
<cfif isFirst>
<cfset isFirst = false />
<cfelse>
,
</cfif>
<cfoutput>
#key# : #anotherPerson[key]#
</cfoutput>
</cfloop>
Solution 2
<cfset resultList = "" />
<cfloop collection="#anotherPerson#" item="key" >
<cfset resultList = ListAppend(resultList, "#key# : #anotherPerson[key]#" ) />
</cfloop>
Cheers!
Just trim the comma when you are done, no skip logic required.
<cfset html = '' />
<cfloop collection="#anotherPerson#" item="key" >
<cfset html &= "#key# : #anotherPerson[key]# , " />
</cfloop>
<cfset html = left(html,len(html)-3) />
<cfoutput>#html#</cfoutput>
Readable, simple, works.

How to find special character from the string

I need to find the special character index in string and it as to be stored in an array variable.
The below code showing only the first special character index but i need to know all index of all the special character in the string .
Tell me how to do
<cfoutput>
<cfset start_var = ArrayNew(1)>
<cfset g_invalidUsername_Char= "!###$%^&*()_+=<>?/\,`~}{[];:.|\""0123456789">
<cfset Firstname="ab!cd!efgh">
<cfif FindOneOf(g_invalidUsername_Char,(trim(FirstName))) NEQ 0>
<cfset QAQC = 0>
<cfset AR=" Firstname can only have ' and - .<br>">
<cfset ARClass ="ARBad">
<cfset start_var= findoneof(g_invalidUsername_Char,FirstName)>
#start_var#
#RemoveChars(FirstName, start_var, 1)#
</cfif>
</cfoutput>
I tried Rereplace function too
<cfoutput>
<cfset start_var = ArrayNew(1)>
<cfset g_invalidUsername_Char= "! # ## $ % & * ( ) _ + = <> ? / , ` ~ } { [ ] ; : . | "" 0 1 2 3 4 5 6 7 8 9 \ ">
<cfset FirstName="ab!cd""efgh">
<cfset var_num=0>
<cfif FindOneOf(g_invalidUsername_Char,(trim(FirstName))) NEQ 0>
<cfset QAQC = 0>
<cfset AR=" Firstname can only have ' and - .<br>">
<cfset ARClass ="ARBad">
<cfloop list="#g_invalidUsername_Char#" index="x" delimiters=" ">
#x#<br>
<cfset FirstName = ReReplace(FirstName,"[#x#]", "", "ALL")>
#FirstName#
</cfloop>
</cfif>
</cfoutput>
but in rereplace function these "\^" two special character is not accepting

Extraction from string

I have the following code and i am trying to figure a way to make it work like below: string1 contains all the numbers of CPt Codes and String will contain its all Details. I tried using GetToken Functionality but i am still figuring what i am missing here
<cfset string = "CPT Codes= 20101 : EXPLORE WOUND CHEST - 06/25/2013,CPT Codes= 20150 : EXCISE EPIPHYSEAL BAR - 06/25/2013,CPT Codes= 2019F : DILATED MACULAR EXAM DONE - 06/25/2013 ">
How i can again subside it to make it work like this:
<cfset string1 = "20101,20150,2019f">
<cfset string2 = "EXPLORE WOUND CHEST - 06/25/2013,EXCISE EPIPHYSEAL BAR - 06/25/2013,DILATED MACULAR EXAM DONE - 06/25/2013">
I solved it, anyone who needs such info can do it like this:
<cfset string = "CPT Codes= 20101 : EXPLORE WOUND CHEST - 06/25/2013,CPT Codes= 20150 : EXCISE EPIPHYSEAL BAR - 06/25/2013,CPT Codes= 2019F : DILATED MACULAR EXAM DONE - 06/25/2013 ">
<cfset delimis = "=,:">
<cfset generateLst = ''>
<cfset generateTextlst = ''>
<cfloop list="#string#" index="k">
<cfset getString = GetToken(k,1,delimis)>
<cfset getID = GetToken(k,2,delimis)>
<cfset generateLst = ListAppend(generateLst,getID)>
<cfset getText = GetToken(k,3,delimis)>
<cfset generateTextlst = ListAppend(generateTextlst,getText)>
</cfloop>
<cfdump var="#generateLst#" label="ID Input">
<cfdump var="#generateTextlst#" label="Text Input">

ColdFusion: pick first non null value from a list

In JavaScript, you can do this:
var a = null;
var b = "I'm a value";
var c = null;
var result = a || b || c;
And 'result' will get the value of 'b' because JavaScript short-circuits the 'or' operator.
I want a one-line idiom to do this in ColdFusion and the best I can come up with is:
<cfif LEN(c) GT 0><cfset result=c></cfif>
<cfif LEN(b) GT 0><cfset result=b></cfif>
<cfif LEN(a) GT 0><cfset result=a></cfif>
Can anyone do any better than this?
ColdFusion doesn't have nulls.
Your example is basing the choice on which item is an empty string.
If that is what you're after, and all your other values are simple values, you can do this:
<cfset result = ListFirst( "#a#,#b#,#c#" )/>
(Which works because the standard list functions ignore empty elements.)
Note: other CFML engines do support nulls.
If we really are dealing with nulls (and not empty strings), here is a function that will work for Railo and OpenBlueDragon:
<cffunction name="FirstNotNull" returntype="any" output="false">
<cfset var i = 0/>
<cfloop index="i" from="1" to="#ArrayLen(Arguments)#">
<cfif NOT isNull(Arguments[i]) >
<cfreturn Arguments[i] />
</cfif>
</cfloop>
</cffunction>
Then to use the function is as simple as:
<cfset result = FirstNotNull( a , b , c ) />