更新 2
我在排序函数中添加了权重查找,将性能和稳定性提高了大约 100%,因为之前的排序函数没有考虑所有类型,并且作为 1 == "1"
正如@Esailija 指出的那样,结果取决于数组的初始顺序。
问题的目的是改进 Answer我的,我喜欢这个问题,因为它被接受了,我觉得有一些性能可以挤出排序功能。我在这里问了这个问题,因为我没有太多线索可以从哪里开始。
也许这也让事情变得更清楚
更新
我改写了完整的问题,因为很多人说我不够具体,我尽力说明我的意思。另外,我重写了 sort
功能以更好地表达问题的意图。
如下例所示
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))
问题是,如何有效地对数组 B 进行排序,以便对对象的任何引用或基元的值,通过相同的 compareFunction、排序的数组 A 共享与以前完全相同的位置。
就像上面的例子
结果数组应符合规则的地方。
a
的元素'和 arrayCurr 包含 b
的元素b[n] === a[n]
例如 b[5] === a[5]
我目前的方法是在 arrayPrev 中标记对象,以便在 arrayCurr 中对它们进行相应的排序,然后再次删除标记。但这似乎没有那么有效。
这是当前
sort
使用的功能。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;
}
}
继承人 Fiddle以及 JSPerf (随意添加您的片段)
和老Fiddle
最佳答案
如果您知道数组包含相同的元素(重复次数相同,可能顺序不同),那么您可以将旧数组复制到新数组中,如下所示:
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 中返回。因此,数组必须包含相同元素且重复次数相同。
关于javascript - 在 Array A 之后对 Array B 排序,这样引用和相等的 Primitives 保持准确的位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16969241/