更新2
我在sort函数中添加了一个权重查找,它将性能提高了大约100%以及稳定性,因为之前的sort函数没有考虑所有类型,而1 == "1"
结果是sort
取决于数组的初始顺序,正如@Esailija指出的那样。
问题的目的是改进我的Answer,我喜欢这个问题,因为它被接受了,我觉得有一些性能可以挤出排序功能。我在这里问了这个问题,因为我没有很多线索可以从哪里开始 也许这会使事情更清晰
我改写了完整的问题,因为很多人都说我不够具体,我尽力说出我的意思。另外,我重写了var x = {
a:"A Property",
x:"24th Property",
obj: {
a: "A Property"
},
prim : 1,
}
x.obj.circ = x;
var y = {
a:"A Property",
x:"24th Property",
obj: {
a: "A Property"
},
prim : 1,
}
y.obj.circ = y;
var z = {};
var a = [x,x,x,null,undefined,1,y,"2",x,z]
var b = [z,x,x,y,undefined,1,null,"2",x,x]
console.log (sort(a),sort(b,a))
函数以更好地表达问题的意图。
让 arrayPrev 成为数组( A ),其中 A 由0到n组成元素的S' (电子)
以下示例说明
a
问题是,如何有效地对数组B 进行排序,以便对对象的任何引用或基元的值共享完全与以前相同的位置,通过相同的 compareFunction,已排序,数组A 。
与上面的例子一样
结果数组应符合规则。
b
和 arrayCurr 包含元素 s' b[n] === a[n]
的
b[5] === a[5]
例如sort
我目前的方法是在 arrayPrev 中标记对象,以便在 arrayCurr 中对其进行相应的排序,然后再次删除标记。但这似乎并不那么有效。
下面是当前使用的function sort3 (curr,prev) {
var weight = {
"[object Undefined]":6,
"[object Object]":5,
"[object Null]":4,
"[object String]":3,
"[object Number]":2,
"[object Boolean]":1
}
if (prev) { //mark the objects
for (var i = prev.length,j,t;i>0;i--) {
t = typeof (j = prev[i]);
if (j != null && t === "object") {
j._pos = i;
} else if (t !== "object" && t != "undefined" ) break;
}
}
curr.sort (sorter);
if (prev) {
for (var k = prev.length,l,t;k>0;k--) {
t = typeof (l = prev[k]);
if (t === "object" && l != null) {
delete l._pos;
} else if (t !== "object" && t != "undefined" ) break;
}
}
return curr;
function sorter (a,b) {
var tStr = Object.prototype.toString
var types = [tStr.call(a),tStr.call(b)]
var ret = [0,0];
if (types[0] === types[1] && types[0] === "[object Object]") {
if (prev) return a._pos - b._pos
else {
return a === b ? 0 : 1;
}
} else if (types [0] !== types [1]){
return weight[types[0]] - weight[types[1]]
}
return a>b?1:a<b?-1:0;
}
}
函数。
{{1}}
答案 0 :(得分:2)
从描述中可以看出,您只需使用排序功能:
function sortOb(a,b){a=JSON.stringify(a);b=JSON.stringify(b); return a===b?0:(a>b?1:-1);}
var x = {a:1};
var y = {a:2};
var a = [1,x,2,3,y,4,x]
var b = [1,y,3,4,x,x,2]
a.sort(sortOb);
b.sort(sortOb);
console.log (a,b);
答案 1 :(得分:2)
如果您知道数组包含相同的元素(具有相同的重复次数,可能以不同的顺序),那么您可以将旧数组复制到新数组中,如下所示:
function strangeSort(curr, prev) {
curr.length = 0; // delete the contents of curr
curr.push.apply(curr, prev); // append the contents of prev to curr
}
如果您不知道数组包含相同的元素,那么按照您的要求进行操作是没有意义的。
根据您链接的内容判断,您可能正在尝试确定数组是否包含相同的元素。在这种情况下,您提出的问题不是您要问的问题,而基于排序的方法可能根本不是您想要的。相反,我建议使用基于计数的算法。
如果到达步骤4,则每个项目在第一个阵列中的显示次数与在第二个阵列中的次数相同。否则,它将在步骤3.1或3.3中检测到。如果任何项目在第一个数组中出现的次数多于第二个数组,则第一个数组会更大,并且算法将在步骤1中返回。因此,数组必须包含具有相同重复次数的相同元素。
答案 2 :(得分:1)
您的函数始终会返回sort.el
的副本,但您可以更轻松:
var sort = (function () {
var tmp;
function sorter(a, b) {
var types = [typeof a, typeof b];
if (types[0] === "object" && types[1] === "object") {
return tmp.indexOf(a) - tmp.indexOf(b); // sort by position in original
}
if (types[0] == "object") {
return 1;
}
if (types[1] == "object") {
return -1;
}
return a > b ? 1 : a < b ? -1 : 0;
}
return function (el) {
if (tmp) {
for (var i = 0; i < el.length; i++) {
el[i] = tmp[i]; // edit el in-place, same order as tmp
}
return el;
}
tmp = [].slice.call(el); // copy original
return tmp = el.sort(sorter); // cache result
};
})();
请注意,我将sort.el
替换为tmp
和一个闭包。小提琴:http://jsfiddle.net/VLSKK/
编辑:这(以及您原来的解决方案)
a
但
答案 3 :(得分:-1)
试试这个
function ComplexSort (a, b)
{
if(typeof a == "object") {
a = a.a;
}
if(typeof b == "object") {
b = b.a;
}
return a-b;
}
var x = {a:1};
var y = {a:2};
var a = [1,x,2,3,y,4,x]
var b = [1,y,3,4,x,x,2]
a.sort(ComplexSort);
b.sort(ComplexSort);
console.log ("Consistent", a,b);