X

Array.sort(customSortFunction:Function)隐藏的陷阱

排序是计算机内经常进行的一种操作,其目的是将一组“无序”的记录序列调整为“有序”的记录序列。
AS3中的Array.sort就是实现排序的工具,它有多种用法,不过使用自定义排序函数时需要注意。 为了更容易的理解下面问题,先弄明白一个排序算法相关的概念:稳定性。
稳定排序:假设在待排序的元素中,存在两个或两个以上的记录具有相同的关键字(或值),在用某种排序法排序后,若这些相同关键字(或值)的元素的相对次序仍然不变,则这种排序方法是稳定的。 而我们下面的代码跟稳定性无关的,因为不存在相同的元素。

通常我们会写以下“错误代码”:

var a:Array = [3.3,2.4,1.5,0];
a.sort(fun);
trace(a);
function fun(a:Number, b:Number):Number
{
    return a-b;
}

排序结果为:

0,2.4,1.5,3.3

我们再来看看另一种方式(注意对返回结果进行了取整操作):

var a:Array = [3.3,2.4,1.5,0];
a.sort(fun);
trace(a);
function fun(a:Number, b:Number):Number
{
    return int(a-b);
}

大家都知道Array.sort是冒泡排序,是根据前(<0)、后(>0)、当前(==0)这3种状态来排的。
但是这里的自定义排序函数的返回值会自动取整(int(returnValue))。 如果结果为(0,1), (-1,0) 注意为开区间,那么自动转换为整数后为0,进而不进行排序,然后运行结果将与我们想要的不一致。

其实第一种自定义排序函数并没有错,只是它只适用于要排序的值都是整数或者每两个值相差不小于1(可以为0)。 安全的排序函数为:

function fun(a:Number, b:Number):Number
{
    if(a>b) return 1;
    else if(a<b) return -1;
    return 0;
}

排序结果为:

0,1.5,2.4,3.3

其实这也算是Array.sort的一个bug了,我找文档没有提到说自定义排序函数返回值会自动取整。

This post was last modified on 2019 年 03 月 04 日 00:44

View Comments (6)

This website uses cookies.