我想知道如何使用某种排序优先级创建自定义sortOn函数。我有一个更复杂的案例,但我主要想知道如何构建好的排序函数。
假设我有这个未分类的数据对象列表:
var myList = [
{drink: {amount: 1, name: "cola"}},
{drink: {amount: 5, name: "beer"}},
{food: {amount: 7, name: "cake"}},
{drink: {amount: 3, name: "fanta"}},
{drink: {amount: 4, name: "tea}},
{other: {amount: 1, name: "table"}},
{food: {amount: 4, name: "mars"}},
{food: {amount: 5, name: "pizza"}},
{food: {amount: 4, name: "cake"}},
{other: {amount: 12, name: "chair"}},
{food: {amount: 14, name: "chips"}},
{drink: {amount: 6, name: "coffee}},
{food: {amount: 8, name: "chips"}},
{food: {amount: 6, name: "pizza"}},
{food: {amount: 1, name: "food"}}
]
好的,想要使用以下规则进行排序:
first: sort in this order: food, drinks, others (note, thats not alphabetical)
then: sort on amount, BUT on food, pizza's + cakes must be on top
在理想情况下,它看起来像这样(手动创建):
var myList = [
{food: {amount: 5, name: "pizza"}},
{food: {amount: 6, name: "pizza"}},
{food: {amount: 4, name: "cake"}},
{food: {amount: 7, name: "cake"}},
{food: {amount: 1, name: "food"}},
{food: {amount: 4, name: "mars"}},
{food: {amount: 8, name: "chips"}},
{food: {amount: 14, name: "chips"}},
{drink: {amount: 1, name: "cola"}},
{drink: {amount: 3, name: "fanta"}},
{drink: {amount: 4, name: "tea}},
{drink: {amount: 5, name: "beer"}},
{drink: {amount: 6, name: "coffee}},
{other: {amount: 1, name: "table"}},
{other: {amount: 12, name: "chair"}}
]
同样,这完全不是一个真实世界的例子,但我有一些案例(甚至更深的嵌套对象),我想应用这些规则。
是否可以创建一些排序顺序查找列表(类似这样),或者这是不可行的?
priorityList = [
food:[
name:["pizza", "tea", rest],
amount: Array.ASCENDING}
],
drink,
other
]; // etc..
我想学习如何制作这种排序功能。我喜欢看Javascript或Actionscript解决方案,但其他语言也可以。有这个图书馆吗?我是否必须遍历所有项目,创建条件,在案例中推送/取消移位或使用自定义sort()
功能吗?我需要一些指导如何以实用/有效的方式解决这个问题。
提前致谢!
答案 0 :(得分:2)
你需要在脑海中分开这两个问题。
一个是排序:给出一个可比对象列表,从"最低"中排序。最高的"这是一个完全解决的问题。别担心。
另一个是比较:给定两个对象,即#34;第一个"?鉴于您编写的规范,以及任何两个对象A和B,您可以说-1(对象A是第一个),0(它们等同于排序目的)或1(对象B是第一个)。 / p>
编写该函数(用您最喜欢的语言)并将其传递给语言的内置排序库,以便快速排序。
答案 1 :(得分:1)
你是对的,你必须返回-1,0或1,但这并不意味着你无法处理它内部的复杂排序,虽然它意味着你必须自定义代码你遇到的每一个案例。像这样的东西会起作用:
function myCustomSort(firstObject, secondObject):int
{
// Is firstObject a food and the second not? firstObject goes in front.
// Are both objects a food?
// Is firstObject's name pizza and the second not?
// firstObject goes in front.
//Are both objects' names pizza? Return 0 - they're equivalent.
//ETC.
}
理想情况下,您希望支持类似您所提供的架构的示例。我建议在根目录中使结构与在子结构中相同(因此您可以在每个级别上运行相同的代码),您的示例将如下所示:
priorityList = {
"consumingType":[
"food":{
"name":[
"pizza",
"tea"
],
amount: Array.ASCENDING
},
"drink",
"other"
],
amount: Array.ASCENDING
};
实际解决方案可能略有不同,具体取决于实际结构(无论您的数据是JSON还是对象)和什么语言 - 但这里是AS3 的入门者,我还没有测试过;这应该指向正确的方向。
首先,我会编写一个递归排序函数来处理排序的一层,然后检查是否有子图层或返回:
function handleComplexSorting( sortingObject, first, second ) {
var result:int = 0;
//Extracting the property name of first/second will differ,
//but pretty sure this is how you do it in AS3.
var firstValue:int = findSortValueForProperty(first[0], sortingObject[0]);
var secondValue:int = findSortValueForProperty(second[0], sortingObject[0]);
if( firstValue > secondValue ) {
//firstValue should go first.
result = -1;
}
else if(firstValue < secondValue){
//secondValue should go first.
result = 1;
}
else {//equal
var childSortingObject:Object;
if( hasChildSorting(sortingObject, childSortingObject) ){
//return result of recursion
result = handleComplexSorting(childSortingObject, first, second);
}
else {
result = 0;
}
}
return result;
}
findSortValueForProperty函数将是你添加升序/降序的地方,我把它遗漏了,但你只需要检查哪一个并反转结果值。这里的值由数组中其索引的倒数确定(首先出现的值最高,最后一个出现最低值,而不是 - 0值)。
function findSortValueForProperty(property:String, priorityProperties:Array):int {
var resultValue:int = 0;
var index = 0;
for each( var currentProperty:String in priorityProperties ) {
if(property == currentProperty) {
resultValue = priorityProperties.length - index;
break;
}
++index;
}
return resultValue;
}
最后,检查对象是否有子排序要求。这实际上是行不通的,它只期望第一项可能有子排序。我也不是100%你可以通过索引来访问Object的变量,就像我(sortingObject[0]
)(你绝对可以迭代它们)。
function hasChildSorting(sortingObject:Object, outChild:Object):Boolean {
var result:Boolean = false;
if( sortingObject[0] is Object ) {
result = true;
outChild = sortingObject[0];
}
}
return result;
}
对于AS3,请参见get string representation of a variable name in as3以按字符串访问变量。 如果你想用其他东西做这件事,你还需要你的语言reflection。