如何在ColdFusion中对结构数组进行排序

Kip*_*Kip 19 sorting coldfusion struct

我在ColdFusion中有一系列结构.我想根据结构中的一个属性对这个数组进行排序.我怎样才能做到这一点?我找到了StructSort函数,但它需要一个结构,我有一个数组.

如果纯粹在ColdFusion中这是不可能的,那么在Java中是否可能以某种方式(可能使用Arrays.sort(Object[], Comparator))?

Tom*_*lak 16

这是与原版非常相似的东西StructSort().它也支持这个pathToSubElement论点.

<cffunction name="ArrayOfStructSort" returntype="array" access="public" output="no">
  <cfargument name="base" type="array" required="yes" />
  <cfargument name="sortType" type="string" required="no" default="text" />
  <cfargument name="sortOrder" type="string" required="no" default="ASC" />
  <cfargument name="pathToSubElement" type="string" required="no" default="" />

  <cfset var tmpStruct = StructNew()>
  <cfset var returnVal = ArrayNew(1)>
  <cfset var i = 0>
  <cfset var keys = "">

  <cfloop from="1" to="#ArrayLen(base)#" index="i">
    <cfset tmpStruct[i] = base[i]>
  </cfloop>

  <cfset keys = StructSort(tmpStruct, sortType, sortOrder, pathToSubElement)>

  <cfloop from="1" to="#ArrayLen(keys)#" index="i">
    <cfset returnVal[i] = tmpStruct[keys[i]]>
  </cfloop>

  <cfreturn returnVal>
</cffunction>
Run Code Online (Sandbox Code Playgroud)

用法/测试:

<cfscript> 
  arr = ArrayNew(1);

  for (i = 1; i lte 5; i = i + 1) {
    s = StructNew();
    s.a.b = 6 - i;
    ArrayAppend(arr, s);
  }
</cfscript> 

<cfset sorted = ArrayOfStructSort(arr, "numeric", "asc", "a.b")>

<table><tr>
  <td><cfdump var="#arr#"></td>
  <td><cfdump var="#sorted#"></td>
</tr></table>
Run Code Online (Sandbox Code Playgroud)

结果:

ArrayOfStructSort结果

  • 这里的许多其他答案取决于arraySort()回调功能(在CF10中添加)或sort()成员函数(在CF11中添加).Tomalak的答案至少可以回到CF9,我仍然需要支持.谢谢Tomalak! (2认同)

ale*_*ale 12

像往常一样,CFLib.org正是你想要的.

http://cflib.org/udf/ArrayOfStructsSort

/**
* Sorts an array of structures based on a key in the structures.
*
* @param aofS      Array of structures.
* @param key      Key to sort by.
* @param sortOrder      Order to sort by, asc or desc.
* @param sortType      Text, textnocase, or numeric.
* @param delim      Delimiter used for temporary data storage. Must not exist in data. Defaults to a period.
* @return Returns a sorted array.
* @author Nathan Dintenfass (nathan@changemedia.com)
* @version 1, December 10, 2001
*/
function arrayOfStructsSort(aOfS,key){
        //by default we'll use an ascending sort
        var sortOrder = "asc";        
        //by default, we'll use a textnocase sort
        var sortType = "textnocase";
        //by default, use ascii character 30 as the delim
        var delim = ".";
        //make an array to hold the sort stuff
        var sortArray = arraynew(1);
        //make an array to return
        var returnArray = arraynew(1);
        //grab the number of elements in the array (used in the loops)
        var count = arrayLen(aOfS);
        //make a variable to use in the loop
        var ii = 1;
        //if there is a 3rd argument, set the sortOrder
        if(arraylen(arguments) GT 2)
            sortOrder = arguments[3];
        //if there is a 4th argument, set the sortType
        if(arraylen(arguments) GT 3)
            sortType = arguments[4];
        //if there is a 5th argument, set the delim
        if(arraylen(arguments) GT 4)
            delim = arguments[5];
        //loop over the array of structs, building the sortArray
        for(ii = 1; ii lte count; ii = ii + 1)
            sortArray[ii] = aOfS[ii][key] & delim & ii;
        //now sort the array
        arraySort(sortArray,sortType,sortOrder);
        //now build the return array
        for(ii = 1; ii lte count; ii = ii + 1)
            returnArray[ii] = aOfS[listLast(sortArray[ii],delim)];
        //return the array
        return returnArray;
}
Run Code Online (Sandbox Code Playgroud)


小智 6

我没有声誉点来评论上面的@mikest34 帖子,但@russ 是正确的,这个回调不再像解释的那样工作。

Adam Cameron 发现当使用带有回调的 arraySort 时,它不再需要 True/False 响应,而是:

-1,如果第一个参数“小于”第二个参数
0,如果第一个参数等于第二个参数
1,第一个参数比第二个参数“大”

所以正确的回调是:

ArraySort(yourArrayOfStructs, function(a,b) {
    return compare(a.struct_date, b.struct_date);
});
Run Code Online (Sandbox Code Playgroud)

在 CF2016 中测试和工作


jps*_*ain 5

公认的解决方案(来自CFLib.org)并不安全.我尝试了这个我需要在工作中做的事情,并发现在使用浮点数对数字进行排序时会返回错误的结果.

例如,如果我有这些结构:(伪代码)


a = ArrayNew(1);

s = StructNew();
s.name = 'orange';
s.weight = 200;
ArrayAppend(a, s);

s = StructNew();
s.name = 'strawberry';
s.weight = 28;
ArrayAppend(a, s);

s = StructNew();
s.name = 'banana';
s.weight = 90.55;
ArrayAppend(a, s);

sorted_array = arrayOfStructsSort(a, 'weight', 'asc', 'numeric');

迭代排序的数组并打印名称和重量.它将不是正确的顺序,这是将任意键与正在排序的值混合的限制.

  • 要分享的好信息,但由于您没有提出替代解决方案,因此应该对该答案进行评论.您可以将代码示例放入gist/pastebin/etc中以使其适合. (4认同)