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