3

我提前为我的问题的长度道歉!我正在尝试自动为我们的活动制定论文时间表。论文和作者数据在电子表格中提供(我可怜的同事目前使用电子表格逐行手动剪切和粘贴到 Word 文档中)。此电子表格包含我构建计划所需的所有信息,在一致命名的列中,但它可以按任何顺序排列。有点像这样(但真正的论文标题不会方便编号):

Jack Doe - Co-Author - Penn State University - Aerodynamics - Aerodynamics Paper I    
John Doe - Co-Author - Penn State University - Acoustics - Acoustics Paper I
John Smith - Co-Author - University of VA - Acoustics - Acoustics Paper I
Jane Doe - Main Author - Penn State University - Acoustics - Acoustics Paper I
Bob Smith - Main Author - GA Tech - Acoustics - Acoustics Paper II
Jack Smith - Main Author - University of MD - Acoustics - Acoustics Paper III
Jill Smith - Co-Author - University of MD - Acoustics - Acoustics Paper III
Bob Doe - Main Author - Penn State University - Aerodynamics - Aerodynamics Paper I

我的目标是对电子表格数据进行变形,使论文按会话(即声学、空气动力学)、论文标题(即声学论文 I、声学论文 II)、然后按每所大学的作者进行分组和排序。问题是任何给定论文的“主要作者”必须首先列出,其次是来自同一所学校的共同作者(如果有的话),然后是来自其他大学的共同作者。其他合著者可以按任何顺序排列,但也必须按大学分组。

因此,以原始示例为例,它应该是这样的:

ACOUSTICS
Acoustics Paper I
Jane Doe, John Doe, Penn State University; John Smith, University of VA

Acoustics Paper II
Bob Smith, GA Tech

Acoustics Paper III
Jack Smith, Jill Smith, University of MD

AERODYNAMICS
Aerodynamics Paper I
Bob Doe, Jack Doe, Penn State University

我快到了,但我只能做到

ACOUSTICS
Acoustics Paper I
Jane Doe, Penn State University; John Doe, Penn State University; John Smith, University of VA;

Acoustics Paper II
Bob Smith, GA Tech;

Acoustics Paper III
Jack Smith, University of MD; Jill Smith, University of MD;

AERODYNAMICS
Aerodynamics Paper I
Bob Doe, Penn State University; Jack Doe, Penn State University;

我们正在使用 ACF 2016。我正在做的(我的代码在下面)是使用 cfspreadsheet 将电子表格读入查询对象。然后我按会话对输出进行分组,然后按标题与嵌套的 cfoutputs 进行分组。

然后,因为我想不出任何其他方法来识别每篇论文的主要作者并将它们放在首位,所以我遍历该论文的所有作者并添加一个标志来识别他们,并使用 arraySort 对其进行排序。请注意,我不能简单地按作者类型 DESC 排序,因为还有另一种类型,“呈现作者”,为简洁起见,我省略了 (ha)。有时主要作者也可以是呈现作者,因此该类型将是“主要作者呈现作者”。

无论如何,我然后循环排序数组。

以下是我到目前为止所尝试的。我坚持让大学只为每个作者列表显示一次。我尝试在我的 authorArray 循环中放置另一个循环,但我不知道要索引或循环什么,所以它最终只是在每个作者姓名之后输出大学名称。我尝试过使用多维数组,甚至使用查询的查询来尝试构建一个好的、有序的数据结构。但我显然做错了,因为我一直被他们的大学分组作者所困扰。

我当然会很感激任何提示或提示!请注意,我无法更改最初使用此电子表格的要求。但是,一旦我得到它,我就可以对获得所需输出所需的信息做任何事情。所以我完全愿意做出任何改变或重新思考我的整个方法。下面的代码是我得到的最接近的代码。

提前非常感谢大家!这是我目前使用的:

<cfoutput query="queryPapers" group="PrimarySession">
    #PrimarySession#
    <cfoutput group="Title">
       <p>#Title#</p>
        <cfset authorArray = arrayNew(1)>
        <cfoutput>
            <cfset authorStruct = structNew()>
            <cfset authorStruct.firstName = AuthorFirstName>
            <cfset authorStruct.lastName = AuthorLastName>
            <cfset authorStruct.institution = AuthorInstitution>
            <cfset authorStruct.authorType = AuthorType>

            <cfif findNoCase("Main", AuthorType)>
                <cfset authorStruct.authorMain = "A">
            <cfelse>
                <cfset authorStruct.authorMain = "B">
            </cfif>

            <cfset arrayAppend(authorArray, authorStruct)>

            <cfscript>
                arraySort(
                    authorArray,
                    function (e1, e2) {
                        return compare(e1.authorMain, e2.authorMain);
                    }
                );
            </cfscript>
        </cfoutput>

        <cfloop index="i" from="1" to="#arrayLen(authorArray)#">
            #authorArray[i].firstName# #authorArray[i].lastName#,
            #authorArray[i].institution#;&nbsp;
        </cfloop>
    </cfoutput>
</cfoutput>

以下是上述代码的一些实际输出:

Dynamic Stall Investigations
  Sergey Smith,* University of Maryland;  Tobias Lersdorf, German University;  Pascal Marceau, University of Maryland;  

我正试图去

Dynamic Stall Investigations
  Sergey Smith,* Pascal Marceau, University of Maryland;  Tobias Lersdorf, German University

非常感谢您的阅读!

4

1 回答 1

2

你的代码走在正确的轨道上,但我认为你有点过于复杂了。您可以<cfoutput>使用下面的代码段简化嵌套处理。

<!--- Nested output loop for displaying required result --->
<cfoutput query="queryPapers" group="PrimarySession">
    <strong>#Ucase(PrimarySession)#</strong><br />
    <cfoutput group="Title">
        <i>#Title#</i><br />
        <cfoutput group="AuthorInstitution">
            <cfoutput>
                #AuthorFirstName# #AuthorLastName#,
            </cfoutput>
            #AuthorInstitution#; <!--- display institution once per group --->
        </cfoutput>
        <br /><br /> <!--- double-space after each title group --->
    </cfoutput>
</cfoutput>
  1. 通过添加另一层组嵌套并将其显示在额外嵌套组的页脚中,可以解决仅显示一次大学的问题。

  2. 确保主要作者始终是第一位的问题应该在您的预处理中处理。为此,请使用您现有的 if/else 逻辑(“A”代表主要作者,“B”否则)并将其作为额外列添加到您的查询中。这样,您可以在order by输出循环之前的子句中使用它。

更新

所以我在发布我的第一个修订版后意识到存在一个小的逻辑缺陷。它没有出现的原因是因为在使用上面的示例数据时,主要作者总是方便地属于“标题”组中按字母顺序排列在第一位的大学。在看到额外的示例输出后,我意识到这一点,我将这些行添加到我的代码示例中,它也错误地显示如下。

Dynamic Stall Investigations
Sergey Smith, University of Maryland; Tobias Lersdorf, German University;  Pascal Marceau, University of Maryland;

解决方案是使用现有的 authorMain 列(A用于主要作者,B否则)并A2为与主要作者属于同一大学的非主要作者添加另一个值。棘手的部分是您必须检查另一行中的值以确定何时设置A2. 我能想到的最佳解决方案是在添加最初填充的 authorMain 列之后立即添加两个代码块。

<!--- Sort query so "Main Author" is first within PrimarySession and Title --->
<cfquery name="queryPapers" dbtype="query">
    select * from queryPapers
    order by
        PrimarySession, 
        Title, 
        AuthorMain
</cfquery>

<!--- Loop through above and update NON "Main-Author" rows "A2" if they have same University as "A" rows  --->
<cfset MainInstitution = "">
<cfloop query="queryPapers">
    <cfif queryPapers.authorMain eq "A">
        <cfset MainInstitution = queryPapers.AuthorInstitution>
    <cfelse>
        <cfif MainInstitution eq queryPapers.AuthorInstitution>
             <cfset QuerySetCell(queryPapers, "authorMain", "A2", queryPapers.currentRow)>
        </cfif>
    </cfif>
</cfloop>

首先按 PrimarySession、Title 和 AuthorMain 排序,然后循环遍历记录集并更新行,如果非主要作者与主要作者在同一所大学,则通过使用变量A2进行跟踪。MainInstitution此解决方案生成正确的结果,同时允许所有其他代码保持不变。

您可以看到模拟 OP 场景的代码的第一个修订版和第二个修订版之间的区别。

于 2018-02-19T14:58:49.757 回答