I am getting an Invalid Index 2 error. Though the loop is quite simple
<cfset empID = 3333333>
<cfset Sec_skill = 2,5>
<cfset SecSkillLevel=1,2>
<cfloop from="1" to="#listLen(Sec_skill)#" index="i">
<cfoutput>
#ListgetAt(empID,i)# <br>
#ListGetAt(sec_skill,i)#<br>
#ListGetat(SecSkillLevel,i)#<br>
</cfoutput>
</cfloop>
Need help
The error will be on this line:
#ListgetAt(empID,i)#
empID is not a list, so there is no element 2.
empID has no item in the list at index 2, there is only one item.
Before displaying, it is necessary to check if the item exist in the list.
For example, with convert list to array:
<cfset empID = 3333333>
<cfset Sec_skill = "2,5">
<cfset SecSkillLevel= "1,2">
<cfloop array="#listToArray(Sec_skill)#" item="item" index="i">
<cfoutput>
#ArrayIsDefined(listToArray(empID), i) ? listToArray(empID)[i] : '-'# <br>
#ArrayIsDefined(listToArray(sec_skill), i) ? listToArray(sec_skill)[i] : '-'# <br>
#ArrayIsDefined(listToArray(SecSkillLevel), i) ? listToArray(SecSkillLevel)[i] : '-'# <br>
</cfoutput>
</cfloop>
Related
i see this code in one of the pages, seems annoying, it can be shorted, if i am on Coldfusion 11
https://trycf.com/gist/701515844d5e41549a7b6e61dfafeaa0/lucee5?theme=monokai
Here is the code how its looks like
<cfloop list="#mqry.columnList#" index="col">
<cfset ColRow ="#mqry.columnList#," >
</cfloop>
<cfset x = replace(ColRow,"CONDITION1","CONDITION") & chr(13) & chr(10)>
<cfloop query="mqry">
<cfloop list="#mqry.columnList#" index="colN">
<cfset f = Replace("#mqry[colN][currentRow]#" ,"""","","All")>
<cfset f = REReplaceNoCase("#mqry[colN][currentRow]#" , "<[^>]*(?:>|$)", "", "ALL")>
<cfset x = x & """#_f#"",">
</cfloop>
<cfset x = x & chr(13) & chr(10)>
</cfloop>
the first value i think i can do as:
mquery.columnlist - no need to loop over
There's nothing wrong with the nested loop. You iterate over all rows and then iterate over each cell per row using the column name. I rewrote your code to be easier understandable:
<cfset NEWLINE = (chr(13) & chr(10))>
<cfset DELIM = ",">
<cfset QUOTE = '"'>
<!--- column headers --->
<cfset x = mqry.columnList>
<!--- replace column names as desired --->
<cfset x = replace(x, "CONDITION1", "CONDITION")>
<!--- next line --->
<cfset x &= NEWLINE>
<cfloop query="mqry">
<cfset row = []>
<cfloop list="#mqry.columnList#" index="colN">
<cfset cellValue = mqry[colN][mqry.currentRow]>
<!--- remove all quotes --->
<cfset cellValue = replace(cellValue, QUOTE, "", "ALL")>
<!--- remove tags --->
<cfset cellValue = reReplaceNoCase(cellValue, "<[^>]*(?:>|$)", "", "ALL")>
<!--- prefix with underscore --->
<cfset cellValue = ("_" & cellValue)>
<!--- wrap in quotes --->
<cfset cellValue = (QUOTE & cellValue & QUOTE)>
<cfset row.add(cellValue)>
</cfloop>
<!--- combine cell values into a row --->
<cfset x &= arrayToList(row, DELIM)>
<!--- next line --->
<cfset x &= NEWLINE>
</cfloop>
<cfoutput>#x#</cfoutput>
trying to handle the list deletion but stuck on ts deletion process: here is my small gist which i am working on, any help appreciated
https://trycf.com/gist/aa3871e76db36ad446b770b9bbbb4cec/lucee5?theme=monokai
<cfset lstFirst = "1,2,3,4,5">
<cfset lstMiddle = "6,7,8,9,10">
<cfset lstLast = "11,12,13,14,15">
From the lstFirst I should be able to delete from reverse like 5,4,3,2,1 but i should not be able to
delete from middle of the very next item which is 2
From the lstMiddle if the middle one is 8, i should be able to delete 7,6 and so on or 9,10 but i should not be able to
delete 6,10 without deleting 7 and 9
From the lstLast which is complete reverse of the lstFirst where the last element is selected and i should be able to delete
from 14,13,12 onward but cannot delete from middle or from 11 onward, it must start its deletion from 14 or 15 backwards this is the way i am trying to make it work
**<cfoutput>
<cfset lstFirst = "1,2,3,4,5">
<cfset lstMiddle = "6,7,8,9,10">
<cfset lstLast = "11,12,13,14,15">
<!--- It's work all dynamic values for lstFirst like 1,2,3,4,5 OR 1,2,3,4,5,6,7,8,9,10 OR 1,2,3,4,5,6,7,8,9,10,11,12 etc.... --->
======= Delete all number from reverse and except very next item to middle ====
<cfset convertToArray = listtoarray(lstFirst)>
<cfset getRoundValue =round(arraylen(convertToArray)/2)>
<cfset findMidNextEle = ArraySlice(convertToArray,1,getRoundValue)>
<cfset LfirstMiddle = listgetat(lstFirst,listfind(lstFirst,listlast(arraytolist(findMidNextEle)))-1)>
<cfloop from="#listlen(lstFirst)#" to="1" index="i" step="-1">
<cfset listgetVal = listgetat(lstFirst,i)>
<cfif LfirstMiddle NEQ listgetVal >
<cfset lstFirst =listdeleteat(lstFirst,i)>
</cfif>
<br/><cfdump var="#lstFirst#" /><br/>
</cfloop>
=========== Delete 7,6 and so on or 9,10 and delete 6,10 without deleting 7 and 9 ================================= <br/>
<cfset lstMiddleMiddle = listfind(lstMiddle,listgetat(lstMiddle,listfind(lstMiddle,listlast(mid(lstMiddle,1,listlen(lstMiddle)))))) >
<cfloop from="1" to="#listlen(lstMiddle)#" index="j">
<cfset userList = listlen(lstMiddle)>
<cfif userList GT 3 >
<cfset lstMiddle1 = listdeleteat(lstMiddle,lstMiddleMiddle-1)>
<cfset lstMiddle2 = listdeleteat(lstMiddle1,lstMiddleMiddle)>
<cfset lstMiddleMiddle = listfind(lstMiddle2,listgetat(lstMiddle2,listfind(lstMiddle2,listlast(mid(lstMiddle2,1,listlen(lstMiddle2))))))>
<cfset lstMiddle = lstMiddle2>
<br/><cfdump var="#lstMiddle2#" /></br>
<cfelse>
<cfset lstMiddle3 = listdeleteat(lstMiddle2,1)>
<cfset lstMiddle4 = listdeleteat(lstMiddle3,2)>
<cfbreak/>
</cfif>
</cfloop>
enter code here
<cfdump var="#lstMiddle4#" /> <br/>
=============== Delete from reverse except last number ==========
<!--- It's will work for all dynamic values --->
<cfset LastEle = listlast(lstLast)>
<cfloop from="#listlen(lstLast)#" to="1" step="-1" index="k">
<cfset getCurrentValue = listgetat(lstLast,k)>
<cfif LastEle NEQ getCurrentValue>
<cfset lstLast =listdeleteat(lstLast,k)>
</cfif>
</br><cfdump var="#lstLast#" /><br/>
</cfloop>
</cfoutput>**
If I have a query result like this
type_name | count
-----------------
test1 | 5
test2 | 4
test4 | 7
How to output the count base on the value of the column type_name?
From the table the row value 'test3' doesn't exist, but it doesn't mean it wont exist later after a refresh.
With the below code I will only get the value but looping 3 times since test3 value doesn't exist.
<cfoutput name="query">
<table>
<tr><td><cfif query.type_name eq 'test1'>#query.count#</cfif></td></tr>
<tr><td><cfif query.type_name eq 'test2'>#query.count#</cfif></td></tr>
<tr><td><cfif query.type_name eq 'test3'>#query.count#</cfif></td></tr>
<tr><td><cfif query.type_name eq 'test4'>#query.count#</cfif></td></tr>
</cfoutput>
<cfset testResults = [0,0,0,0]>
<cfloop query="query">
<cfset testResults[right(query.type_name, 1)] = query.count>
</cfloop>
<table>
<cfloop array="#testResults#" index="count">
<td>#count#</td>
</cfloop>
</table>
You should see
5
4
0
7
If you need a more dynamic approach, you can transform your full query result (all columns) to an array of structs:
<!---
<!--- test data --->
<cfset query = queryNew("type_name,count", "VARCHAR,INTEGER")>
<cfset queryAddRow(query, 3)>
<cfset querySetCell(query, "type_name", "test1", 1)>
<cfset querySetCell(query, "count", "5", 1)>
<cfset querySetCell(query, "type_name", "test2", 2)>
<cfset querySetCell(query, "count", "4", 2)>
<cfset querySetCell(query, "type_name", "test4", 3)>
<cfset querySetCell(query, "count", "7", 3)>
--->
<!--- number of tests to list --->
<cfset expectedNumberOfRows = 4>
<!--- remember all columns while transforming query to array of structs --->
<cfset queryColumns = listToArray(query.columnList)>
<!--- initialize array of structs --->
<cfset testResults = arrayNew(1)>
<cfloop from="1" to="#expectedNumberOfRows#" index="i">
<cfset blankResult = structNew()>
<!--- initialize all columns for each row --->
<cfloop array="#queryColumns#" index="columnName">
<cfset blankResult[columnName] = "">
</cfloop>
<!--- default values for specific columns --->
<cfset blankResult["type_name"] = "test#i#">
<cfset blankResult["count"] = "0">
<cfset testResults.add(blankResult)>
</cfloop>
<!--- transfer cell values from each query row to array of structs --->
<cfset queryRowIndex = 1>
<cfloop query="query">
<!--- extract possible row index --->
<cfset testNumber = trim( reReplace(query.type_name, "[^0-9]*([0-9]+)$", "\1") )>
<!--- transfer cells --->
<cfif reFind("^[0-9]+$", testNumber)>
<cfloop array="#queryColumns#" index="columnName">
<cfset testResults[int(testNumber)][columnName] = query[columnName][queryRowIndex]>
</cfloop>
</cfif>
<cfset queryRowIndex++>
</cfloop>
<cfoutput>
<table>
<cfloop array="#testResults#" index="testResult">
<tr>
<td>#testResult.type_name#</td>
<td>#testResult.count#</td>
<!--- add additional columns if desired --->
</tr>
</cfloop>
</table>
</cfoutput>
I have been tasked with shortening a sequence of numbers by replacing internal sequences of 3 or more with a dash for the internal numbers (as in, 3,5,6,7,8,10 would be 3,5-8,10)
Pretty similar to the above, just using lists.
<cfscript>
a = listToArray('3,5,6,7,8,10,11,15,16,17,18');
writeOutput( fNumSeries(a) );
string function fNumSeries( array a) output="false" {
var tempList = '';
var outputList = '';
for ( var i in a ) {
if( listLen(tempList) == 0 ) {
// Nothing in the list
tempList = i;
} else if ( listLen(tempList) ) {
if ( listLast(tempList)+1 == i) {
// i is next in order from the previous list item. Just add to temp list.
tempList = listAppend(tempList, i);
} else if (listLen(tempList) >= 3) {
// current item is not the next item, and the tempList is more than 2 items long, so abbreviate and set templist to the current item.
outputList = listAppend(outputList, listFirst(tempList) & '-' & listLast(tempList));
tempList = i;
} else {
// tempList is less than 3 items long, just append to output and set tempList to the current item.
outputList = listAppend(outputList, tempList);
tempList = i;
}
}
}
// Clean up the remaining item(s) in tempList. If 3 or more, abbreviate, else just append to output.
outputList = listLen(tempList) >= 3 ? listAppend(outputList, listFirst(tempList) & '-' & listLast(tempList)) : listAppend(outputList, templist);
return outputList;
}
</cfscript>
I put the following function together, plus some demo output. It assumes the numbers are in an ordered, non-repeating array. (CF list functions help get to this point.) Is there a more elegant way of doing this?
<cffunction name="fNumSeries" output="1" hint="parses array of numbers for display: 1|2|3|6|7|9|10|11|12 would be 1-3, 6, 7, 9-12 ">
<cfargument name="raNums" required="1" type="array">
<cfset raLen=arraylen(raNums)>
<cfif raLen eq 0><CFRETURN "">
<cfelseif raLen eq 1><CFRETURN raNums[1]>
<cfelseif raLen eq 2><CFRETURN raNums[1] & "," & raNums[2]>
</cfif>
<cfset numSeries="">
<cfset numHold=raNums[1]>
<cfset seqHold=raNums[1]>
<cfset numSeries=raNums[1]><!--- raNums[1]always output the first number --->
<cfloop from="1" to="#raLen#" index="idxItem">
<cfif idxItem gt 1><!--- wait for 2nd element to decide output --->
<cfif numHold+1 neq raNums[idxItem]><!--- reason to output and seqHold+1 neq numHold--->
<cfif seqHold eq numHold>
<cfset numSeries=numSeries & ",#raNums[idxItem]#">
<cfelse>
<cfif seqHold+1 eq numHold><cfset numSeries=numSeries & ","><!--- and numHold+1 neq raNums[1] and seqHold+1 eq numHold --->
<cfelse><cfset numSeries=numSeries & "-">
</cfif>
<cfset numSeries=numSeries & "#numHold#,#raNums[idxItem]#">
</cfif>
<cfset seqHold=raNums[idxItem]>
</cfif>
</cfif>
<cfset numHold=raNums[idxItem]>
</cfloop>
<cfif seqHold neq numHold><!--- display the last element --->
<cfif seqHold+1 eq numHold or raLen eq 2><cfset numSeries=numSeries & ",">
<cfelse><cfset numSeries=numSeries & "-">
</cfif>
<cfset numSeries=numSeries & "#numHold#">
</cfif>
<CFRETURN numSeries>
</cffunction>
<cfset raRa=[
[2,12],
[2,3,12],
[2,4,12],
[2,3,4,12],
[2,8,9,11,12],
[2,9,11,12],
[2,3,8,10,11,12]
]>
<cfoutput>
<cfloop array="#raRa#" index="ra">
#arrayToList(ra)#<br />
#fNumSeries(ra)#<hr>
</cfloop>
</cfoutput>
The code below outputs weekend dates in the current month.
CODE:
<cfparam name="month" default="#DatePart('m', Now())#">
<cfparam name="year" default="#DatePart('yyyy', Now())#">
<cfset ThisMonthYear=CreateDate(year, month, '1')>
<cfset Days=DaysInMonth(ThisMonthYear)>
<cfset ThisDay = 1>
<cfloop condition="ThisDay LTE Days">
<cfset presentDay = CreateDate(year, month, thisday)>
<cfif DayOfWeek(presentDay) EQ '7'>
<cfoutput>#ThisDay#</cfoutput>
<cfelseif DayOfWeek(presentDay) EQ '1'>
<cfoutput>#ThisDay#</cfoutput>
</cfif>
<cfset ThisDay = ThisDay + 1>
</cfloop>
OUTPUT:
6 7 13 14 20 21 27 28
What I'm trying is to pass value of this cfloop in one variable. The code below only displays the last weekend date value.
CODE:
<cfset ThisDay = 1>
<cfset weekDayOfMonth = "">
<cfloop condition="ThisDay LTE Days">
<cfset presentDay = CreateDate(year, month, thisday)>
<cfif DayOfWeek(presentDay) EQ '7'>
<cfset weekDayOfMonth = ThisDay>
<cfelseif DayOfWeek(presentDay) EQ '1'>
<cfset weekDayOfMonth = ThisDay>
</cfif>
<cfset ThisDay = ThisDay + 1>
</cfloop>
<cfoutput>#weekDayOfMonth#</cfoutput>
OUTPUT
28
Question, what do I need fix in my last cfloop code so I can pass loop values into the jsWeekendDates variable?
Any help will be greatly appreciated.
Thank you.
Just figured on my own. Enjoy.
<cfset ThisDay = 1>
<cfset weekDay = "">
<cfloop condition='ThisDay LTE Days'>
<cfset presentDay = CreateDate(year, month, thisday)>
<cfif DayOfWeek(presentDay) EQ '1' OR DayOfWeek(presentDay) EQ '7'>
<cfset weekDay = weekDay & " " & ThisDay">
</cfif>
<cfset ThisDay = ThisDay + 1>
</cfloop>
<cfoutput>#weekDay#</cfoutput>