我需要对一个数组进行排序,但它只能在Chrome中正常运行。在mozilla规范中,我发现了这个文本,但无法解决这个问题:
“此数组的元素已排序。排序不一定 稳定(即,比较相等的元素不一定保留 按原来的顺序)。如果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"
}
]
结果必须是
答案 0 :(得分: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
)。你期望它做什么?
如果
comparefn
不是该数组元素的一致比较函数,则sort的行为是实现定义的。如果所有值
comparefn
,S
和{满足以下所有要求,则函数a
是一组值b
的一致比较函数集合c
中的{1}}(可能是相同的值):符号S
表示a <CF b
;comparefn(a,b) < 0
表示a =CF b
(任一标志);comparefn(a,b) = 0
表示a >CF b
。当给定一对特定值
comparefn(a,b) > 0
和comparefn(a,b)
作为其两个参数时,调用v
始终返回相同的值a
。此外,b
是数字,Type(v)
不是v
。请注意,这意味着对于给定的NaN
和a <CF b
对,a =CF b
,a >CF b
和a
中只有一个为真。
- 调用
b
不会修改此对象。comparefn(a,b)
(反身性)- 如果
a =CF a
,则a =CF b
(对称)- 如果
b =CF a
和a =CF b
,则b =CF c
(a =CF c
的及物性传承- 如果
=CF
和a <CF b
,则b <CF c
(a <CF c
的及物性传承- 如果
<CF
和a >CF b
,则b >CF c
(a >CF c
的及物性传承注意:上述条件是必要且足以确保
>CF
将集合comparefn
划分为等价类,并且这些等价类是完全有序的。
答案 1 :(得分:0)
我的另一个答案解释了为什么你的排序不稳定。这个将解决您的实际问题: - )
您不能使用sort
来解决此类问题,您需要从(无序)边集构造节点列表。只有在没有附加数据的情况下比较两个元素时,才能对数组进行排序。假设您只有两个连接Tokio - Moscow
和Rome - Oslo
,您不知道哪个连接是第一个(没有联系您的计划,但您还没有联系)。相比之下,在比较数字时,您可以轻松地并且始终告诉5大于3(通过计算差异)。
相反,我们需要执行类似this或this的操作 - 构建一个结构,我们可以通过名称轻松访问工作站,并在循环中遇到它们时直接插入连接,以便在最后我们有一个车站连接列表:
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);
});