I have this array of structures setup:
<cfset table_columns = [
{name="Right Name", var_name="right_name", searchable="true", sortable="true"},
{name="Right Type", var_name="right_type", searchable="true", sortable="true"},
{name="Right Description", var_name="right_descr", searchable="true", sortable="true"},
{name="Edit", var_name = "editcol", searchable="false", sortable="false"}
]>
How would I loop through that? Here is an example of what I need to do (which is obviously not working):
<cfloop array="#table_columns#" index="data_index">
{"sName": "#table_columns[data_index]['name']#", "sTitle": "#table_columns[data_index]['var_name']#", "bsearchable": "#table_columns[data_index]['searchable']#", "bsortable": "#table_columns[data_index]['sortable']#"},
</cfloop>
With an array loop, the index value is an element of the array, not a position. Meaning data_index is a structure. So you can output the keys as usual (with either structure or dot notation).
<cfloop array="#table_columns#" index="data_index">
{"sName": "#data_index['name']#", "sTitle": "#data_index['var_name']#", "bsearchable": "#data_index['searchable']#", "bsortable": "#data_index['sortable']#"},
</cfloop>
<cfloop collection="#table_columns#" item="data_index">
This is an approximation taken from the CF docs:
http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-71a6.html
I've never had to do it, but hopefully that'll get you started.
Related
I have an object called jsonJobsOpen and when I dump it the output shows the value for this Object as shown below.
[{
"APPLICATIONCOUNT":0,
"JOBNAME":"Candidate Migration Job ",
"JOBID":"15433AAE-8631-FA8B-AEA7-49E116EF60E1 ",
"JOBCLOSEDATE":" ",
"JOBSTATUSLABELVALUE":"Incomplete",
"ENCRYPTEDURLAPPCOUNT":"event=cms.listApplicantsPersistVars&JobID=15433AAE-8631-FA8B-AEA7-49E116EF60E1&JobAppStatusID=DCA85CD5-A134-7A4B-30E8-49E116F0D702",
"JOBOPENDATE":" ",
"APPLIEDAPPCOUNT":0,
"JOBSTATUSLABELCOLOUR":"D8605F",
"REFERENCE":"Candidate Migration Job ",
"ENCRYPTEDURL":"event=jm.gotoJCW&JobID=15433AAE-8631-FA8B-AEA7-49E116EF60E1",
"ENCRYPTEDURLCANDIDATEASSESSMENT":"event=jm.gotoJCW&JobID=15433AAE-8631-FA8B-AEA7-49E116EF60E1",
"ENCRYPTEDURLAPPLICANTLIST":"event=cms.listApplicantsPersistVars&JobID=15433AAE-8631-FA8B-AEA7-49E116EF60E1"
}]
If there is no value associated with Object then the dump looks like this:
[{
"JOBID":"",
"JOBOPENDATE":"",
"JOBCLOSEDATE":"",
"JOBNAME":"",
"REFERENCE":"",
"ENCRYPTEDURL":"",
"APPLICATIONCOUNT":"",
"ENCRYPTEDURLAPPLICANTLIST":"",
"ENCRYPTEDURLCANDIDATEASSESSMENT":"",
"JOBSTATUSLABELVALUE":"",
"JOBSTATUSLABELCOLOUR":"",
"APPLIEDAPPCOUNT":"",
"ENCRYPTEDURLAPPCOUNT":""
}]
My question here is what condition can I use to check if the value is there or not with this object in ColdFusion?
From Leigh's answer here
In JSON, the [] denotes an array and {} a structure (or object). So your input is actually an array of structures. You need to use an array loop ...
<cfset arrayOfStructs = deserializeJson(jsonJobsOpen)>
<cfloop array="#arrayOfStructs#" index="thisValue">
<!--- Now you can use this condition to check for empty values --->
<cfif StructKeyExists(thisValue, "JOBID") and Len(thisValue.JOBID) GT 0>
...
</cfloop>
I'm doing a couple things there. First deserializing the JSON string into something ColdFusion can handle (an array of structures). Then checking that the JOBID field exists. If it does exist, then also check that it's length is greater than 0 (not empty).
You should be able to do something like this for each element (assuming that the name of your variable containing this JSON is jsonJobsOpen.
Here is a quick ColdFusion Gist that shows an example using your data.
I am having difficulty figuring out how to remove some unwanted characters.
Below is a sample of my array data. I would like to remove all occurences of "Rail National" or remove elements containing the string "Rail National".
If I understand your question correctly, this will completely remove any element from the array that contains the text 'rail national' anywhere in it:
newArray = [
'Adult Child Class',
'Ticket Type',
'I rail national Rail Nation',
'Rail Nationa',
'Rail National',
'Route']
// Remove items from the array
.filter( function(i){
return !(findNocase( i, 'Rail National' ) > 0);
// Edit items in the array
} ).map( function(i){
return replaceNocase( i, 'il Nati', '', 'all' );
} );
The filter function will run the closure against each item in the array and only return that item in the final array if the closure returns true.
http://cfdocs.org/arrayfilter
The map function will return the array with each item potentially modified.
http://cfdocs.org/arraymap
Note, you didn't say what CF engine you're using. This sample code will run on Lucee Server.
<!--- your data --->
<cfset yourArray = [
"Adult Child class",
"Ticket type",
"Elk NIL StD RTN",
"ANYTIME R",
"Start Date",
"Number",
"I Rail National Rail Nation",
"Valid unt",
"Rail Nationa",
"price"
]>
<!--- array for filtered data --->
<cfset filteredArray = []>
<cfloop array="#yourArray#" index="element">
<!--- remove elements (by skipping) that contain "Rail National" (case insensitive) --->
<cfif element contains "Rail National">
<cfcontinue>
</cfif>
<!--- remove all occurences of substring "il Nati" (case insensitive) in element --->
<cfset element = replaceNoCase(element, "il Nati", "", "ALL")>
<!--- additional filters --->
<!--- ... --->
<!--- add/keep element --->
<cfset filteredArray.add(element)>
</cfloop>
<cfdump var="#filteredArray#">
A Regex version, as requested:
CR=chr(13);
myRegEx="(^|[\n])[^Rr\n]*Rail Nationa[^\n]*([\n]|$)";
myList=ArrayToList(myArray,CR);
myList=ReReplace(myList,myRegEx,CR,"All");
myArray=ListToArray(myList,CR);
A chained RegEx version:
CR=chr(13);
myRegEx="(^|[\n])[^Rr\n]*Rail Nationa[^\n]*([\n]|$)";
myArray=myArray.toList(CR).ReReplace(myRegEx,CR,"ALL").ListToArray(CR);
A slightly shorter chain:
myArray=myArray.toList(CR).ReplaceAll(myRegEx,CR).ListToArray(CR);
Indented version - often preferred over one liners:
myArray=myArray
.toList(CR)
.ReplaceAll(myRegEx,CR)
.ListToArray(CR);
Coldfusion 8 version here.
Here is a snipset of my code:
<cfset ColumnNames = structKeyArray(ApiData[1])>
<cfdump var="#ColumnNames#"><!--- lowercase names --->
<cfdump var="#ArrayToList(ColumnNames,",")#"> <!--- need each name in Array in UPPERCASE --->
uCase(ColumnNames) wont work. Do I have to loop it through each item and use uCase?
Thank you
Or even just turn it into a list first using structKeyList(), which you can call uCase() on.
<cfset ColumnNames = uCase(structKeyList(ApiData[1]))>
It is ugly, but you could do:
listToArray( UCase( structKeyList( ApiData[ 1 ] ) ) )
I am converting a ColdFusion application to C# (I'm a CF n00b).
I have a script that performs a cfquery and then cfloop's through the results, and it appears to be trying to compare the current row to its following row. And it appears to be trying to make sure that it doesnt try to read past the end of the array.
<cfquery name="qTripLegs" datasource="#sdb#">
SELECT ...
</cfquery>
<cfloop query="qTripLegs">
<cfif (customs_stop[currentrow] NEQ "" OR fuel_stop[currentrow] NEQ "") AND recordcount GT currentrow AND departure[currentrow] NEQ arrival[currentrow+1]>
It feels like currentrow is 1-based (currentrow will have a value of 1 when it first enters the cfloop). Am I correct? I have looked in the coldfusion documentation and I dont see anything about this.
Yes, queries and arrays in CF are 1-based.
The CurrentRow and RecordCount variables are properties of the query (inside a query loop they are automatically scoped).
<cfloop query="QueryName">...</cfloop> will loop through the entire query*, from 1 to QueryName.RecordCount, and the QueryName.CurrentRow index is automatically populated/incremented appropriately. Its value prior to query loop isn't used.
*(unless cfbreak/etc used)
Also to point out there is generally no need to prevent reading past the end (as above, the query loop handles it), it's only because CurrentRow+1 is being used that it's needed to avoid an error.
query.currentRow()
Returns the current row number
queryCurrentRow(query) → returns numeric
Member Function Syntax
<cfscript>
var myQuery = queryNew("id,title","integer,varchar",[[1,"Charlottes Web"],[3,"The Outsiders"],[4,"Mieko and the Fifth Treasure"]]);
cfloop(query = "myQuery"){
if (title Eq "Mieko and the Fifth Treasure"){
writeOutput(myQuery.currentRow());
}
}
</cfscript>
Got a critical error like: The value cannot be converted to a number. what can be the problem? Since i tried to write this values like:
1. <cfset ortalama=trim(val(db_maliyet_temp))+ds_toplam_maliyet>
2. <cfset ortalama=val(db_maliyet_temp)+ds_toplam_maliyet>
3. <cfset ortalama=db_maliyet_temp+ds_toplam_maliyet>
the first and second are just doesnt count the db_maliyet_temp,
and the 3 give out the error: The value cannot be converted to a number.
value for db_maliyet_temp: 2.806,71
for ds_toplam_maliyet: 394,22
These are not valid numbers. If you would like the total of the numbers, you can try this.
<cfset aryMaliyetNumbers = ListToArray(db_maliyet_temp, ",")>
<cfset aryToplamNumbers = ListToArray(ds_toplam_maliyet, ",")>
<cfset total = ArraySum(aryMaliyetNumbers) + ArraySum(aryToplamNumbers)>
There are several ways to skin this cat. This should at least get you going. Works perfectly on my CF 7 box!
EDIT
After the ridiculous amount of comments to clarify the question, I believe this is the solution.
<cfset db_maliyet_temp = Replace(Replace("2.806,71", ".", ""), ",", ".")>
<cfset ds_toplam_maliyet = Replace(Replace("394,22", ".", ""), ",", ".")>
<cfset total = db_maliyet_temp + ds_toplam_maliyet>
If you want the number without decimals, you can do this:
<cfset db_maliyet_temp = Replace(Replace("2.806,71", ".", ""), ",", ".")>
<cfset ds_toplam_maliyet = Replace(Replace("394,22", ".", ""), ",", ".")>
<cfset total = val(db_maliyet_temp + ds_toplam_maliyet)>
IMPORTANT
You have a much larger problem than a CF error. You need to fix the underlying issue that's causing your number to be formatted incorrectly.
This should do the trick:
<cfscript>
function convertToNumber(num){
return reReplace(reReplace(num,'.','','ALL'),',','.','ALL');
}
</cfscript>
<cfset ortalama=convertToNumber(db_maliyet_temp)+convertToNumber(ds_toplam_maliyet)>
Basically it just removes the '.' since that is formatting not needed for math and replaces the ',' with a decimal so that it can be treated as a number. This will only work if ALL the numbers you are going to be dealing with are formatted this way, if there are any formatted like 1,200.90 then you will have to be a little more fancy.
Have you tried the LSParseNumber() function?:
http://cfquickdocs.com/cf9/#lsparsenumber
Or the val() function?:
http://cfquickdocs.com/cf9/#val
Also, it may be easier to clean the data before it get's entered either with client-side validation (if it's coming from a form) or server-side validation.