ArraySum of a list - coldfusion

I am trying to add all the values of all the numbers in a list.
So this is what I tried,
<cfloop query="get_total_merchant">
<cfset tx_amt_total = #tx_amount# + (#tx_amount# * (#merchantFee#/100))>
#ArraySum(tx_amt_total)#
</cfloop>
So basically what tx_amt_total will display is something like 1 2 3 4. So I am trying to add 1 + 2 + 3 + 4 which should give me 10.
However, from what I tried, I am getting an error message: Object of type class java.lang.Double cannot be used as an array
So how do I fix my code?

<cfset tx_amt_total = 0 />
<cfloop query="get_total_merchant">
<cfset tx_amt_total += (tx_amount + (tx_amount * (merchantFee/100))) />
</cfloop>
should be enough. You don not need arraySum()

Related

ColdFusion List Error Invalid list index 2

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>

using List to delete elements from middle, first position and last position in sequence

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>**

Breaking a Value List to show 5 records in one Line and then move to Next line and so on

I have the following code where i am tryin to use mod operator to list 5 items on the line and then move to next line, On the single line it should display 5 items and then in next line, it should display the remaining items, if the remaining items are more than 5, it should go to 3rd line then
i am trying this code: but it not doing anything
<cfset items = "1,2,3,4,5,6,7,8,9,0">
<cfif listLen(items) mod 5>
<cfoutput>
#items##Chr(10)##chr(13)#TEST
</cfoutput>
</cfif>
it is displaying all in one line
There are a couple of things wrong with your code.
You are not looping over the list to display each item.
Chr(10) and Chr(13) (linefeed and carriage return) do not display in HTML and your browser.
I modified your code like this:
<cfset counter = 0>
<cfset items = "1,2,3,4,5,6,7,8,9,0,a,b,c">
<cfloop index="thisItem" list="#items#">
<cfset counter = counter + 1>
<cfif counter mod 5>
<cfoutput>#thisItem#, </cfoutput>
<cfelse>
<cfoutput>#thisItem#<br></cfoutput>
</cfif>
</cfloop>
Try it here
and here is an example of that same logic using cfscript syntax:
<cfscript>
counter = 0;
items = "1,2,3,4,5,6,7,8,9,0,a,b,c";
for (counter = 1; counter lte listlen(items); counter++) {
if (counter mod 5) {
writeOutput('#listGetAt(items,counter)#, ');
} else {
writeOutput('#listGetAt(items,counter)#<br>');
}
}
</cfscript>
Try it here
The code I have given you here can be cleaned up a bit but hopefully it is easy to understand for you.
Here is another approach if you are on CF10+:
<cfscript>
// Items List
items_list = "1,2,3,4,5,6,7,8,9,0,a,b,c";
// Convert to array
items_array = items_list.listToArray( "," );
// Item Count
itemCount = arrayLen( items_array );
// Display
for ( i = 1; i <= itemCount; i += 5) {
writeOutput( items_array.slice( i, i + 5 - 1 > itemCount ? itemCount % 5 : 5 ).toList( "," ) & "<br>" );
}
</cfscript>
Here is the TryCF.
Here is another approach.
<cfset items = "1,2,3,4,5,6,7,8,9,0,a,b,c">
<cfoutput>
<cfloop from="1" to="#listLen(items)#" index="i">
#listGetAt(items,i)#
<cfif i mod 5 eq 0>
<br>
<cfelseif i neq listLen(items)>
,
</cfif>
</cfloop>
</cfoutput>
Results in
1 , 2 , 3 , 4 , 5
6 , 7 , 8 , 9 , 0
a , b , c

How to (selectively) convert array elements to a list of values

Given the array below, how do I convert it to a simple list of values?
<cfdump var="#arguments.ServiceTextArray#">
Array Elements:
1 3567_no
2 3584_yes
3 3642_yes
4 3643_yes
5 3644_no
6 3645_no
7 3646_no
Specifically, how do I extract values with the "yes" suffix and produce a list like this?
3584,3642,3643
Thanks in advance.
Would this help? There will always be better solution than this.
<cfset myList = "">
<cfloop from="1" to="#Arraylen(myArray)#" index="index">
<Cfif right(myArray[index],3) EQ "yes">
<cfset myList = listAppend(myList, listFirst(myArray[index], '_'))>
</Cfif>
</cfloop>
<cfoutput>#myList#</cfoutput>
This is partly an extension to Henry answer but should be exactly what your after:
<cfscript>
tmpArray = ['567_no','584_yes','3642_yes','3643_yes','3644_no','3645_no','3646_no'];
list = "";
for (item in tmpArray)
if (listLast(item, "_") == "yes")
list = listAppend(list, listFirst(item, "_"));
writeDump(list);
var list = "";
for (item in array)
if (ListLast(item, "_"))
list = listAppend(list, val(item));
Using the Underscore.cfc library (CF 10 only):
filteredArray = _.filter(arguments.ServiceTextArray, function(val) {
return (val contains 'yes');
});
resultArray = _.map(filteredArray, function(val) {
return left(val, 4);
});
list = arrayToList(resultArray);
(I created this library, BTW)

ColdFusion looping through [only part] of a list

Really struggling with finding a way to loop through only part (or half maybe?) of a coldfusion list. I've got an if statement set up to check the length of the list and if it is over 30... I want to split the list into the first 30 and the remainder? Not sure if that's the best solution though. I really don't need much detail I'm sure I can figure that much out myself I am more looking just to be pointed in the right direction...
Rather than looping over the list, loop from 1 to a number, and use listGetAt() in the loop. For the remainder of the list, just loop from #myvar + 1# to #listLen#.
<cfoutput>
<cfloop from="1" to="#myVar#" index="idx">
#listGetAt( myList, idx )#<br />
</cfloop>
</cfoutput>
Granted, it's not the most efficient method. If you encounter performance issues, might want to convert the list to an array via listToArray(), and then do:
<cfset myArray = listToArray( myList ) />
<cfoutput>
<cfloop from="1" to="#myVar#" index="idx">
#myArray[ idx ]#<br />
</cfloop>
</cfoutput>
You can make use of the underlying java functions.
<cfscript>
testList = "1,2,3,4,5,6,7,8,9,10,...,43,44";
listAsArray = listToArray(testList);
testChunk = listAsArray.subList(0,30);
</cfscript>
will give you an array "testChunk" with the first 30 items in the list. You can now easily loop over the elements of the Array.
To make this more clear, here is an example:
<cfscript>
testList = "";
maxChunkLength = 30;
for (i=1;i lte 100; i=i+1){
testList = listAppend(testList, i);
}
numOfChunks = ceiling(listLen(testList)/maxChunkLength);
listAsArray = listToArray(testList);
numOfItems = arraylen(listAsArray);
for (k=1;k lte numOfChunks; k=k+1){
startItem = (k - 1) * maxChunkLength;
endItem = startItem + maxChunkLength;
if (endItem gt numOfItems){
endItem = numOfItems;
}
writeOutput(listAsArray.subList(startItem, endItem).toString() & "<br />");
}
</cfscript>
it really depends on what you are trying to accomplish, how the 2 separated sets of data will be used and whst type of data you have in the list... does the data really need to be separated? can you just:
<cfloop from="31" to="#listLen(myList)#" index="i">
#listGetAt(myList, i)#
</cfloop>
If you don't need to take the extra step of separating into 2 lists or arrays, save your self some coding & execution time
Also - if your starting point changes, you can always:
<cfloop from="#start#" to="#listLen(myList)#" index="i">
#listGetAt(myList, i)#
</cfloop>
-sean
In CF10 or Railo 4, you could use the first() and rest() functions from Underscore.cfc to split up your list:
_ = new Underscore();
myArray = listToArray(myList);
firstThirty = _.first(myArray, 30);
remaining = _.rest(myArray, 31);
_.first() and _.rest() both return new arrays based on the index passed into them. The methods simply delegate to the native arraySlice() function, but they can help you write more expressive code.
Note: I wrote Underscore.cfc