1

我的任务是通过用内部数字的破折号替换 3 或更多的内部序列来缩短数字序列(如 3,5,6,7,8,10 将是 3,5-8,10)

4

2 回答 2

2

与上面非常相似,只是使用列表。

<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>
于 2015-07-27T18:13:51.267 回答
1

我把下面的函数放在一起,加上一些演示输出。它假设数字是有序的、非重复的数组。(CF 列表函数有助于达到这一点。)有没有更优雅的方法呢?

<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>
于 2015-07-27T16:07:23.013 回答