2013-03-24 70 views
0

我需要排序一个数组,但它只能在Chrome中正常工作。在Mozilla的规范,我发现这个文本但仍无法修复此:排序()在mozilla&opera中无法正常工作

“这个数组的元素进行排序排序不一定 稳定(即,比较相等不一定留元素如果comparefn不是未定义的,则它应该是 函数,它接受两个参数x和y,并返回一个负值 如果x < y,如果x = y则为零,如果x> y则返回正值, Y“。

而这个链接https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/sort可能是它会帮助你,我

这是我的代码

arr.sort(sortTrip); 

function sortTrip(a, b) { 

    if (a.to != b.from) return 1; 
    if (a.to == b.from) return -1; 

} 

这是arr

var arr = [ 
    { 
     "from": "Moscow", 
     "to": "Rome", 
     "transport": "NSB Regiontog Train", 
     "seat": "25" 
    }, 
    { 
     "from": "Oslo", 
     "to": "Paris", 
     "transport": "NSB Regiontog Train", 
     "seat": "25" 
    }, 
    { 
     "from": "Helsinki", 
     "to": "Tokio", 
     "transport": "NSB Regiontog Train", 
     "seat": "25" 
    }, 
    { 
     "from": "Tokio", 
     "to": "Moscow", 
     "transport": "NSB Regiontog Train", 
     "seat": "25" 
    }, 
    { 
     "from": "Paris", 
     "to": "New-York", 
     "transport": "NSB Regiontog Train", 
     "seat": "25" 
    }, 
    { 
     "from": "Rome", 
     "to": "Oslo", 
     "transport": "NSB Regiontog Train", 
     "seat": "25" 
    } 
] 

结果必然是

  • 赫尔辛基 - 东京
  • 东京 - 莫斯科
  • 莫斯科 - 罗马
  • 罗马 - 奥斯陆
  • 奥斯陆 - 巴黎
  • 巴黎 - 新纽约
+1

护理提供有效的输入,你得到了不同的结果? – 2013-03-24 15:55:02

+0

当然,在浏览器和Mozilla的歌剧 – 2013-03-24 16:00:32

+0

不同的结果,它清楚地说,你需要返回-1,0和1,所以当a.to == b.from它应该是0,而当a.to TheBrain 2013-03-24 16:03:09

回答

0

我的其他答案解释了为什么你的排序不稳定。这一个将解决你的实际问题:-)

你不能使用sort这种类型的问题,你想从一组(无序)的边缘构造节点的列表。对数组进行排序仅适用于如果可以将比较两个元素而没有附加数据。假设你只有两个连接Tokio - MoscowRome - Oslo,你不知道他们哪一个先来(不联系你的计划,但你还没有)。相比之下,比较数字时,您可以轻松并始终告诉5大于3(通过计算差异)。

相反,我们需要做的是这样thisthis - 建立一个结构,我们可以很容易地通过名称访问的站点和循环它们在直接插入连接时,我们遇到了他们,让最终我们有一个列表

var map = {}; 
for (var i=0; i<arr.length; i++) { 
    var con = arr[i]; 
    map[con.from] = con; 
} 

所以,我们现在可以构建您的路线某种链表:

for (var from in map) { 
    var connTo = map[from].to; 
    if (connTo in map) 
     map[from].next = map[connTo]; 
} 

及删去从地图上所有目的地找到启动站:由站连接

for (var from in map) 
    for (var next = map[from]; next; next = next.next) 
     delete map[next.to]; 
for (from in map) // there's only one key left 
    var start = from; // "Helsinki" 

让我们构建的路由作为站名的数组:

var route = [start], 
    conn = map[start]; 
while (conn) { 
    route.push(conn.to) 
    conn = conn.next; 
    // maybe delete conn.next as we don't need it any more 
} 
// route: 
// ["Helsinki", "Tokio", "Moscow", "Rome", "Oslo", "Paris", "New-York"] 

或结果是你想要的,连接列表:

var arr = []; 
for (var conn = map[start]; conn; conn = conn.next) 
    arr.push(conn); 

有了这样的计划,我们现在甚至可以构造一个比较函数来对原始数组进行排序:

arr.sort(function(a, b) { 
    // compare the positions of the departure stations in the route 
    return route.indexOf(a.from) - route.indexOf(b.from); 
}); 
+0

它是genious。真。感谢您对本精彩的回答,你救了我的大脑在安全) – 2013-03-24 18:25:32

+0

以及我发现我不太明白这个片段:'为(VAR从地图) 为(VAR下一=地图[从];未来;未来= next.next) 删除地图[下一个。至]; (从地图上) var start = from;'我想了解它是如何工作的,但在这个野生循环中感到困惑'(var next = map [from]; next; next = next.next)' – 2013-03-25 06:45:41

+0

我可以在没有删除的情况下找到开始的地方,但用'if'可以找到起始地的名字不是到达地的名字之一吗? – 2013-03-25 07:09:15

4

参见Sorting in JavaScript: Should every compare function have a "return 0" statement?


if (a.to != b.from) return 1; 
if (a.to == b.from) return -1; 

这不是一个一致的比较函数(违反了反身性,即compare(x, x) == 0,例如)。你期望它做什么?

引述ES5.1 spec on sort

如果comparefn是[...]不是此数组的元素一致的比较函数,排序行为是实现定义。

函数comparefn是一组值S的一致比较函数,如果所有的下面在设定S满足所有值ab,和c(可能是相同的值)的要求:符号a <CF b装置comparefn(a,b) < 0; a =CF b表示comparefn(a,b) = 0(任一符号);和a >CF b表示comparefn(a,b) > 0

调用comparefn(a,b)给出了具体的一对值ab作为它的两个参数的时总是返回相同的值v。此外,Type(v)是Number,并且v不是NaN。请注意,这意味着a <CF b,a =CF ba >CF b中的一个对于给定的一对ab将是正确的。

  • 调用comparefn(a,b)不会修改此对象。
  • (自反)
  • 如果a =CF b,然后b =CF a(对称)
  • 如果a =CF bb =CF c,然后a =CF c(的=CF传递性)
  • 如果a <CF bb <CF c,然后a <CF c(的<CF传递性)
  • 如果a >CF bb >CF c,则a >CF c(传递性为>CF

注意:上述的条件是必要的,足以确保comparefn划分集合S成等价类,并且这些等价类全序。

+1

我认为不止于此,它是不是一个有效的comparefn(A,B),根据该规范,因为它并不适用于例如反身性(http://es5.github.com/# x15.4.4.11)ie compareTo(a,a)不是0 – 2013-03-24 16:02:06

+0

这看起来像是塑造成一个有趣的答案。为了帮助您解决这个问题,请在v8中进行排序Chrome https://code.google.com/p/v8/source/browse/trunk/src/array.js(这是针对较小阵列和QuickSort的插入排序对于较大的),Spidermonkey使用合并排序https://github.com/funkaster/spidermonkey/blob/master/js/src/ds/Sort.h – 2013-03-24 16:07:49

+0

@Benjamin:完全。也违反了'> CF'的传递性。 – Bergi 2013-03-24 16:08:08

相关问题