Crockford - 数组排序 - 第81页

时间:2013-10-17 21:36:17

标签: javascript sorting

var by = function (name) {
    return function (o, p) {
        var a, b;
        if (typeof o === 'object' && typeof p === 'object' && o && p) {
            a = o[name];
            b = p[name];
            if (a === b) {
                return 0;
            }
            if (typeof a === typeof b) {
                return a < b ? -1 : 1;
            }
            return typeof a < typeof b ? -1 : 1;
        } else {
            throw {
                name: 'Error',
                message: 'Expected an object when sorting by ' + name
            };
        }
    };
};

var s = 
[
    {first: 'Joe', last: 'Besser'},
    {first: 'Moe', last: 'Howard'},
    {first: 'Joe', last: 'DeRita'},
    {first: 'Shemp', last: 'Howard'},
    {first: 'Larry', last: 'Fine'},
    {first: 'Curly', last: 'Howard'}
];


s.sort(by('first'));// s is [
// {first: 'Curly', last: 'Howard'},
// {first: 'Joe', last: 'DeRita'},
// {first: 'Joe', last: 'Besser'},
// {first: 'Larry', last: 'Fine'},
// {first: 'Moe', last: 'Howard'},
// {first: 'Shemp', last: 'Howard'}
// ]

当我实际执行此代码时,在排序数组中, 乔·德里塔(Joe DeRitta)追随乔·贝塞尔(Joe Besser),这种做法更多 因为这是他们进入原版的顺序 阵列。作者说DeRita在排序中出现在Besser之前 阵列。我没有在本书的勘误表中找到这个。

(1)这是一些错字(我怀疑它,我猜代码是运行的) 或者只是另一件“最近”的事情(在 最近5 - 6年)JavaScript的变化?

(2)低于作者说: “排序方法不稳定,所以:

s.sort(by('first')).sort(by('last'));

无法保证产生正确的序列。“

这真的是什么稳定的类型? http://en.wikipedia.org/wiki/Category:Stable_sorts 我想这本书中发生的事情是连续两种, 并且没有太多机会按正确顺序排序, 但我认为这与“稳定排序”的概念无关。 是吗?

想象一下这两个名字:

[
    { first: "Alfred", last: "Williams" },
    { first: "Barbara", last: "Charles" }
]

如果我们按名字排序,阿尔弗雷德将永远是第一名。 如果按姓氏排序,芭芭拉将永远是第一位的。 所以...如果我们这样做:

s.sort(by('first')).sort(by('last'));

结果将仅取决于我们最后排序的内容(在这种情况下) 我们按姓氏排序。)

我误解了什么(好吧,我承认我没有想过 最近稳定排序),这里提到的稳定排序是什么?

1 个答案:

答案 0 :(得分:2)

关于代码s.sort(by('first')).sort(by('last'));,您说:

  

我认为本书中发生的事情是两个连续的排序

这是完全正确的。如果调用该代码,则列表将首先按名字排序,然后完全按姓氏使用。

  

但我认为这与“稳定排序”的概念无关。是吗?

实际上,有一种关系。 stable sorting algorithm将遵守以下规则:

  

如果两个项目相等,那么它们的相对顺序将被保留,这样如果一个在输入中位于另一个之前,它也将在输出中位于另一个之前。

在你的例子中,考虑名字“Shemp Howard”和“Curly Howard”。 如果排序算法是稳定的,并且您希望按姓氏和名字排序名称列表,则可以调用两个后续排序。 s.sort(by('first'))将把这两项列入顺序:Curly Howard,Shemp Howard。随后调用s.sort(by('last')) 如果使用稳定的排序算法将比较姓氏“Howard”和“Howard”,确定姓氏相等,保留原始顺序< / strong>即可。这意味着任何具有相同姓氏的项目将保留在按名字排序时产生的顺序。

不幸的是,正如Crockford所指出的那样,javascript的Array.sort is not necessarily stable以及后来的两个排序将无法保证按原始顺序保留相同的项目。