【问题标题】:ColdFusion Sorting/AssignmentColdFusion 排序/分配
【发布时间】:2017-11-22 04:54:02
【问题描述】:

我有两个列表:一个是动态的,基于学生的记录数,另一个是学生......即 001,002,003 等和 123456(学生数据)。我需要一些帮助才能随机分配学生其中一个数字。例如,如果我有 5 个学生(123456、234561 等),我需要能够将 001,002 等随机分配给这些学生。到目前为止,撞墙了。以下是我目前所拥有的:

<cfquery name="testjd" datasource="student">
    SELECT SoonerID FROM dbo.CurrentStudentData
    WHERE status = 'Student' OR status = 'JD'
</cfquery>

<cfset testList = valueList(testjd.soonerid)>
<cfset totalRecordsJd = #testjd.recordcount#>
<cfloop from="001" to="#totalRecordsJd#" index="i">
    <cfset examNo = i>
    <cfif len(i) is 1>
        <cfset examNo = "00" & i>
    <cfelseif len(i) is 2>
        <cfset examNo = "0" & i>
    </cfif>
    <cfif not listFind(usedJDExams, examNo)> 
        #examNo#<!---is NOT being used!---><br/>
    </cfif>
</cfloop>

【问题讨论】:

  • ColdFusion 有一个 randrange 函数,您可以将它与它的列表和数组函数结合使用。
  • 为什么不查询添加随机数
  • 丹,非常感谢您的反馈。我有我的范围,只是不确定如何根据上述情况将值从一个列表随机分配到另一个列表。
  • Manuel,如果你不介意,请解释一下。
  • 您使用的是哪个数据库?

标签: coldfusion coldfusion-9


【解决方案1】:

CF9 比更高版本少了一点乐趣。我相信这应该可行(除了我的查询模型)。

https://trycf.com/gist/3667b4a650efe702981cb934cd325b08/acf?theme=monokai

首先,我创建虚假查询。

<!--- 
    Simple faked up query data. This is just demo data. I think this 
    queryNew() syntax was first available in CF10.  
--->
<cfscript>
    testjd = queryNew("SoonerID", "varchar", [
        ["123456"],
        ["564798"],
        ["147258"],
        ["369741"]
    ]);
</cfscript>

现在我已经有了需要测试的学生列表,我为这些测试创建了一个数字数组。

<!--- Create array of Available Exam Numbers --->
<cfset examNos = ArrayNew(1)>
<cfloop from=1 to=100 index="i">
    <cfset examNos[i] = right('00' & i,3)>
</cfloop>

我们现在结合两组数据来获得分配给学生的考试编号。

<!--- Loop through the query and build random assignments --->
<cfloop query="#testjd#">
    <!---Get random exam no.--->
    <cfset examNo = examNos[randrange(1,arrayLen(examNos))]> 
    <!---Build struct of exam assignments--->
    <cfset testAssignments[SoonerID] = examNo>
    <!---Delete that num from exam array. No reuse.--->
    <cfset blah = arrayDelete(examNos,examNo)>
</cfloop>

这给了我们

<cfoutput>
    <cfloop collection="#testAssignments#" item="i">
        For User #i#, the test is #testAssignments[i]#.<br>
    </cfloop>
</cfoutput>

The unused tests are: <cfoutput>#ArrayToList(examNos)#</cfoutput>.

-------------------------------------------------------------------- 

For User 369741, the test is 054. 
For User 147258, the test is 080. 
For User 564798, the test is 066. 
For User 123456, the test is 005. 
The unused tests are: 
     001,002,003,004,006,007,008,009,010
    ,011,012,013,014,015,016,017,018,019,020
    ,021,022,023,024,025,026,027,028,029,030
    ,031,032,033,034,035,036,037,038,039,040
    ,041,042,043,044,045,046,047,048,049,050
    ,051,052,053,055,056,057,058,059,060
    ,061,062,063,064,065,067,068,069,070
    ,071,072,073,074,075,076,077,078,079
    ,081,082,083,084,085,086,087,088,089,090
    ,091,092,093,094,095,096,097,098,099,100.

OP 代码的一些代码审查说明:

1) 使用数组或结构比使用列表更容易。

2) cfloop from="001" to="#totalRecordsJd#": from "001" 是一个字符串,您正在与整数进行比较。 ColdFusion 将在后台将“001”转换为一个数字,以便它可以真正开始循环。注意预期的数据类型,并确保使用预期使用的参数。

3) cfif len(i) is 1...:首先,一次性构建此字符串并对其进行修整的处理更少 - right('00' &amp; i,3)。其次(这是个人的挑剔),iseq 基本上做同样的事情,但我一直认为将is 应用于字符串类事物并将eq 应用于数字类对象是一种很好的做法东西。

================================================ =======================

对于 CF10+,我会使用类似的东西

https://trycf.com/gist/82694ff715fecd328c129b255c809183/acf2016?theme=monokai

<cfscript>
    // Create array of random string assignments for ExamNo
    examNos = [] ;
    for(i=1; i lte 100;i++) {
        arrayAppend(examNos,right('00'& i,3)) ;
    }

    ///// Now do the work. ////
    //Create a struct to hold final results
    testAssignments = {} ;
    // Loop through the query and build random assignments
    for(row in testjd) {
        // Get random exam no.
        examNo = examNos[randrange(1,arrayLen(examNos))] ; 
        // Build struct of exam assignments
        structInsert(testAssignments, row.SoonerID, examNo) ; 
        // Delete that num from exam array. No reuse.
        arrayDelete(examNos,examNo) ; 
    }
</cfscript>

【讨论】:

  • 肖恩,我可以向你保证....100%....我没有投反对票。相信我,每个人的建议都很有帮助。
  • @JohnEubanks 哈哈,不用担心。我刚刚看到我输入了答案,几分钟之内,有人对你的问题和问题的两个答案都投了反对票。一定要喜欢连续投票的人。 :-/
  • Shawn,关于这个的最后一个问题:为了对表执行插入操作,我需要将其转换回列表吗?
  • ExamNos 的列表从何而来?如果考试编号首先来自那里,您可能不需要为此从数据库中出来。您是否要插入另一个数据库字段?你能为这些字段提供一个简单的数据库结构模式吗?
  • 通过学生测试更新您的数据库:sqlfiddle.com/#!6/ee17d/1/0 这对我来说似乎有点乱,但它适用于小批量。我还没有测试过更大的集合。 NEWID() 可以减慢查询速度。此更新不排除已使用的测试,对于小型测试集而言,它可能看起来不是随机的。它只会从活动测试列表中提取,并且只会更新当前学生列表。您可以刷新 UPDATE 以查看它的变化。
【解决方案2】:

如果是small 查询,为什么不直接使用 NEWID() 对记录(伪)进行随机排序?由于记录已经随机化,您可以使用query.currentRow 来构建“examNo”。

<cfquery name="testjd" datasource="student">
    SELECT SoonerID 
    FROM   CurrentStudentData
    WHERE  status IN ('Student', 'JD')
    ORDER BY NewID()
</cfquery>

<cfoutput query="yourQuery">
   #yourQuery.SoonerID# #NumberFormat(yourQuery.currentRow, "000000")#<br>
</cfoutput>

【讨论】:

  • Shawn 提出了一个很好的问题……这些真的是随机数吗?如果它们实际上是 db 表中的 id,则可以使用更短的方法进行插入。
【解决方案3】:

这是一个格式化的评论。运行此查询后:

<cfquery name="testjd" datasource="student">
    SELECT SoonerID FROM dbo.CurrentStudentData
    WHERE status = 'Student' OR status = 'JD'
</cfquery>

这样做:

<cfset QueryAddColumn(testJd, "newcolumn", arrayNew(1))>

然后循环查询并使用QuerySetCell 将值分配给新列。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-02
    • 2021-11-30
    相关资源
    最近更新 更多