Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sorting 如何在ColdFusion中对结构数组进行排序_Sorting_Coldfusion_Struct - Fatal编程技术网

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

Sorting 如何在ColdFusion中对结构数组进行排序,sorting,coldfusion,struct,Sorting,Coldfusion,Struct,我在ColdFusion中有一个结构数组。我想根据结构中的一个属性对这个数组进行排序。我怎样才能做到这一点?我找到了StructSort函数,但它需要一个结构,我有一个数组 如果纯粹在ColdFusion中不可能做到这一点,那么在Java中是否可能(可能使用Arrays.sort(Object[],Comparator))?与往常一样,CFLib.org完全符合您的要求 下面是与原始的StructSort()非常相似的内容。它还支持pathToSubElement参数 <cffuncti

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


如果纯粹在ColdFusion中不可能做到这一点,那么在Java中是否可能(可能使用
Arrays.sort(Object[],Comparator)
)?

与往常一样,CFLib.org完全符合您的要求


下面是与原始的
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>

使用/测试:

<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>

arr=ArrayNew(1);
对于(i=1;i lte 5;i=i+1){
s=StructNew();
s、 a.b=6-i;
ArrayAppend(arr,s);
}
结果:


如果您不想使用自定义方法,Coldfusion有structSort方法。是的,它使用嵌套结构对结构进行排序,但返回数组,因此可用于实现相同的结果。

接受的解决方案(来自CFLib.org)不安全。我用它做了一些我在工作中需要做的实验,发现它在用浮点数排序数字时返回错误的结果

例如,如果我有以下结构:(伪代码)

迭代排序数组并打印名称和权重。 它的顺序不对,这是混合的一个限制 具有排序值的任意键。

您可以使用来完成所需的操作:

arrayOfStructs = [
    {myAttribute: 10},
    {myAttribute: 30},
    {myAttribute: 20}
];

_ = new Underscore();

sortedArray = _.sortBy(arrayOfStructs, function (struct) {
    return struct.myAttribute;
});
Underline.cfc允许您定义自定义比较器并委托arraySort()。您可以使用它对数组、结构、查询或字符串列表进行排序,但它总是返回一个数组


(免责声明:我写了下划线.cfc)

我想把我的两分钱扔到这里。我遇到了一个需要使用多个键对结构数组进行排序的情况。最后,我使用构造的查询进行排序。函数将结构数组作为第一个参数,然后是表示排序顺序的结构数组,如下所示:

<cfset result = sortArrayOfStructsUsingQuery(myArrayOfStructs,[
{name = "price", type = "decimal", sortOrder = "asc"},
{name = "id", type = "integer", sortOrder = "asc"}
])>

在sortarrayofstructusingquery函数中,我仅基于传入的键构造一个查询,然后对该查询进行排序。然后,我循环查询,从数组中找到与当前查询行中的数据匹配的structure元素,并将该结构添加到我返回的数组中

这段代码中完全可能有一个我的测试还没有发现的漏洞(我还没有很多用例),但如果它对任何人都有用,就在这里。希望它有用,如果有任何明显的漏洞,我很高兴听到他们

(请注意:我使用“局部”范围表示将保留在函数中的所有变量,使用“r”范围表示我打算返回的任何变量,不管值多少钱)


挑选*
来自[local]。查询
按#local.ORDER.子句订购#

新的CF闭包支持实际上更容易实现

下面是我今天处理的一个示例,我想按存储在结构中的日期对结构数组进行排序。我是按降序排序的

ArraySort(yourArrayOfStructs, function(a,b) {
    if ( DateCompare(a.struct_date, b.struct_date) == -1 ) {
        return true;
    } else {
        return false;
    }
});

我不能完全相信这一点,因为我从Ray Camden的《2012年的闭包》中改编了它。

这是一个基于Tomalak答案的UDF,它也支持自定义对象(例如,一些基于Railo的CMS使用)。此函数与ColdFusion 9兼容

<cffunction name="sortStructArray" returntype="array" access="public">
  <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 _sct = StructNew()>
  <cfset var _aryKeys = ArrayNew(1)>
  <cfset var arySorted = ArrayNew(1)>
  <cfif IsStruct(base[1])>
    <!--- Standard structure --->
    <cfloop from="1" to="#ArrayLen(base)#" index="i">
      <cfset _sct[i] = base[i]>
    </cfloop>
    <cfset _aryKeys = StructSort(_sct, sortType, sortOrder, pathToSubElement)>
    <cfloop from="1" to="#ArrayLen(_aryKeys)#" index="i">
      <cfset arySorted[i] = _sct[_aryKeys[i]]>
    </cfloop>
  <cfelse>
    <!--- Custom object (e.g., Catalog) --->
    <cfloop from="1" to="#ArrayLen(base)#" index="i">
      <cfset _sct[i] = StructNew()>
      <cfset _sct[i][pathToSubElement] = base[i][pathToSubElement]>
    </cfloop>
    <cfset _aryKeys = StructSort(_sct, sortType, sortOrder, pathToSubElement)>
    <cfloop from="1" to="#ArrayLen(_aryKeys)#" index="i">
      <cfset arySorted[i] = base[_aryKeys[i]]>
    </cfloop>
  </cfif>
  <cfreturn arySorted>
</cffunction>

我没有对上面@mikest34帖子发表评论的声誉点,但是@russ认为这个回调不再按照解释的方式工作是正确的

Adam Cameron发现,当将arraySort与回调一起使用时,不再需要真/假响应,而是:

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

因此,正确的回调是:

ArraySort(yourArrayOfStructs, function(a,b) {
    return compare(a.struct_date, b.struct_date);
});

在CF2016中测试和工作

使用arraySort回调使用多个键对结构数组进行排序的简单解决方案:

它将要排序的结构数组作为第一个参数,将sortkey/sortorder对格式的结构数组作为第二个参数,例如[{sortkey:'FirstName',sortorder:'asc'},{sortkey:'LastName',sortorder:'desc'}]

<cffunction name="arrayOfStructsSort" access="public" returntype="array" output="false" hint="This sorts an array of structures.">
    <cfargument name="aOfS" type="array" required="yes" />
    <cfargument name="key_sortOrder" type="array" required="yes" />
    <cfscript>

    arraySort(
        aOfS,
        function (a, b) {
            for (var i = 1; i lte arrayLen(key_sortOrder); i = i + 1) {
                var prop = key_sortOrder[i];
                var key = prop.key;
                var sortOrder = prop.sortOrder;
                if (a[key] lt b[key]) {
                    if (sortOrder eq 'desc') {
                        return 1;
                    } else {
                        return -1;
                    }
                }
                if (a[key] gt b[key]) {
                    if (sortOrder eq 'desc') {
                        return -1;
                    } else {
                        return 1;
                    }
                }
            }
            return 0;
        }
    );

    return aOfS;

    </cfscript>

</cffunction>

阿莱索特(
aOfS,
功能(a、b){
对于(变量i=1;i lte arrayLen(键排序器);i=i+1){
var prop=密钥排序器[i];
var key=prop.key;
var sortOrder=prop.sortOrder;
如果(a[键]lt b[键]){
if(排序器等式'desc'){
返回1;
}否则{
返回-1;
}
}
如果(a[键]gt b[键]){
if(排序器等式'desc'){
返回-1;
}否则{
返回1;
}
}
}
返回0;
}
);
返回AOF;
简单地说:

<cfset ArraySorted = arrayOfStructsSort(arrayToBeSorted,arrayOfSorkeys)>

“键”应该是变量范围的,我相信。@Edward:当然,我错过了那个。谢谢你的提示。很多的ot
ArraySort(yourArrayOfStructs, function(a,b) {
    return compare(a.struct_date, b.struct_date);
});
<cffunction name="arrayOfStructsSort" access="public" returntype="array" output="false" hint="This sorts an array of structures.">
    <cfargument name="aOfS" type="array" required="yes" />
    <cfargument name="key_sortOrder" type="array" required="yes" />
    <cfscript>

    arraySort(
        aOfS,
        function (a, b) {
            for (var i = 1; i lte arrayLen(key_sortOrder); i = i + 1) {
                var prop = key_sortOrder[i];
                var key = prop.key;
                var sortOrder = prop.sortOrder;
                if (a[key] lt b[key]) {
                    if (sortOrder eq 'desc') {
                        return 1;
                    } else {
                        return -1;
                    }
                }
                if (a[key] gt b[key]) {
                    if (sortOrder eq 'desc') {
                        return -1;
                    } else {
                        return 1;
                    }
                }
            }
            return 0;
        }
    );

    return aOfS;

    </cfscript>

</cffunction>
<cfset ArraySorted = arrayOfStructsSort(arrayToBeSorted,arrayOfSorkeys)>