Search code examples
coldfusion

Correct way to use ListValueCount


I need to count total of ? in a given string. Here is my code:

<cfscript>
    myString="UPDATE personnel SET personnel_id = ?, personnel_name = ?, personnel_nric = ?, personnel_staff_num = ?, personnel_designation = ?, personnel_department = ?, personnel_appointed_start_date = ?, personnel_appointed_end_date = ?, personnel_inspection_date = ?, personnel_org_id = ?, lt_dispose_personnel_type_id = ? WHERE id = 49;"
    writeOutput("The count of ? is: " & ListValueCount(myString,"?",","))
</cfscript>

but here is my output : The count of ? is: 0. My expected output is 11. What is the correct way to use ListValueCount ? Thanks in advance.

CFfiddle : https://cffiddle.org/app/file?filepath=0dee010d-6bde-4ac9-939b-9867b53f128c/da1fade3-c26b-4703-a0b8-0037eddf6345/ecea7294-fba5-464e-ab2f-b919dd94f650.cfm


Solution

  • The issue is that ListValueCount() counts instances of a specified value in a list (see listValueCount at cfdocs ).

    Because your delimiter is "," the list will break down into the following list item values (see here the trimmed values):

    1. "UPDATE personnel SET personnel_id = ?"
    2. "personnel_name = ?"
    3. "personnel_nric = ?"
    4. "personnel_staff_num = ?"
    5. "personnel_designation = ?"
    6. "personnel_department = ?"
    7. "personnel_appointed_start_date = ?"
    8. "personnel_appointed_end_date = ?"
    9. "personnel_inspection_date = ?"
    10. "personnel_org_id = ?"
    11. "lt_dispose_personnel_type_id = ? WHERE id = 49;"
    

    Because you are looking for the specific item value "?", no item can be found: Each of the string values above consist of more than one question mark!

    Solution 1: Use a regular expression search, e.g.,

    <cfscript>
        myString="UPDATE personnel SET personnel_id = ? , personnel_name = ?  , personnel_nric = ?, personnel_staff_num = ?, personnel_designation = ?, personnel_department = ?, personnel_appointed_start_date = ?, personnel_appointed_end_date = ?, personnel_inspection_date = ?, personnel_org_id = ?, lt_dispose_personnel_type_id = ? WHERE id = 49;"
        writeOutput("The count of ? is: " & reFind("\?.+?,?", myString,1,true,"ALL").len())
    </cfscript>
    

    Solution 2: If you are using a more modern cfml engine, another possibility is to loop your list with a listReduce() member function like so:

    <cfscript>
    myString="UPDATE personnel SET personnel_id = ?, personnel_name = ?, personnel_nric = ?, personnel_staff_num = ?, personnel_designation = ?, personnel_department = ?, personnel_appointed_start_date = ?, personnel_appointed_end_date = ?, personnel_inspection_date = ?, personnel_org_id = ?, lt_dispose_personnel_type_id = ? WHERE id = 49;"
    writeOutput("The count of ? is: " & myString.listReduce( 
        ( acc, element ) => {
            if( findNoCase( "?", element ) ){
                return acc+1;
            }else{
                return acc;
            }
    
        }
    
        , 0, ","
        ));</cfscript>
    

    Solution 3 would be the classic way using cfloop and loop through each item and do findNoCase similar to the listReduce function above.

    Side note: I suppose you are doing some kind of dynamic SQL query or debugging. Please be carefull creating those, especially when creating dynamic SQL queries. The regex solution 1 may have side effects according to the content of the list you are creating. You need to test it carefully!