Javascript好的部分:排序不稳定?

时间:2015-05-09 02:20:00

标签: javascript sorting

在书" Javascript:The Good Parts"中,作者提到了概念"稳定"在第81页。Link to Google book

但是,我发现本书给出的例子与排序是否稳定无关。 Wiki

我在这里遗漏了什么?

所以书中的例子如下:

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')).sort(by('last'));   不保证产生正确的序列。

但是这个例子实际上并没有证明排序是否稳定。如果按先排序然后按最后排序,则将覆盖按第一部分排序。结果如下:

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

我知道JS排序不能保证稳定。 Herehere。但我不认为这本书以正确的方式对待这个话题。我的问题是,我不知道我的理解是否正确。如果我错了,我想知道原因。

2 个答案:

答案 0 :(得分:4)

假设您按名字排序,然后按姓氏重新排序。你得到这样的东西:

[
    { first: 'Joe', last: 'Besser'},
    { first: 'Joe', last: 'DeRita'},
    { first: 'Larry', last: 'Fine'},
    ?
    ?
    ?
]

前三个要素保证是那三个,但其余的是什么?它们都具有相同的姓氏'Howard',因此不清楚它们应该处于什么顺序。

如果排序不稳定,那些项目可以按任何顺序排列。你可以得到这个:

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

其中最后三个元素与名字的顺序相反。但是,通过稳定排序,这些元素将保证按照先前排序的顺序排列。按名字排序将Curly排在Moe之前,Moe领先于Shemp,所以你可以保证得到这个:

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

答案 1 :(得分:0)

看看你提供的链接中是如何定义“稳定”的,以及“Javascript:The Good Parts”的作者如何使用这个词,我可以看到这本书似乎确实使用了稍微不同的定义。 / p>

作者认为Javascript排序不“稳定”,因为您无法使用级联排序条件而无需执行额外的编程工作。在其他一些语言中,你可以。例如,在C#中,以下是有效的LINQ:

// Sorts by two columns at once, no overwriting.
var sorted = s.OrderBy(p => p.FirstName).ThenBy(p => p.LastName);

在我看来,这就是作者在说“稳定”时的想法。

但是,您在问题中链接到的Wiki和Mozilla文档表明,“稳定”排序不应更改具有相同排序值的项目的相对顺序。所以使用以下输入数据:

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'}
];

如果我在Javascript中做s.sort(by('last'));并且它稳定,Moe Howard将永远在Shemp Howard之前上市,而Curly Howard将永远在Shemp之后上市。排序只会考虑相同的姓氏,而不会改变它们的相对顺序。如果您按姓氏对上述列表进行排序并获得以下结果:

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

这意味着维基百科的定义并没有“稳定”,因为Shemp,Moe和Curly相对于彼此改变了立场。

所以回答我相信你的问题:“Javascript:The Good Parts”中的代码没有证明维基百科所定义的排序不稳定性,因为作者显然是根据该词的不同定义进行操作。