Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/472.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 将数组B排序到数组A之后,以便引用和相等的基元保持精确的位置_Javascript_Arrays_Sorting - Fatal编程技术网

Javascript 将数组B排序到数组A之后,以便引用和相等的基元保持精确的位置

Javascript 将数组B排序到数组A之后,以便引用和相等的基元保持精确的位置,javascript,arrays,sorting,Javascript,Arrays,Sorting,更新2 我给排序函数增加了一个权重查找,它使性能提高了大约100%,稳定性也提高了,因为以前的排序函数没有考虑所有类型,并且作为 1=“1”< /代码>,结果取决于数组的初始顺序,正如Esailija指出的。 这个问题的目的是改进我的这个问题,我喜欢这个问题,因为它被接受了,我觉得有一些性能可以从排序函数中挤出。我在这里问这个问题,因为我没有多少线索可以从哪里开始。 也许这也让事情变得更清楚了 更新 我重新表述了整个问题,因为很多人说我不够具体,我尽了最大的努力来说明我的意思。另外,我重写了so

更新2

我给排序函数增加了一个权重查找,它使性能提高了大约100%,稳定性也提高了,因为以前的排序函数没有考虑所有类型,并且作为<代码> 1=“1”< /代码>,结果取决于数组的初始顺序,正如Esailija指出的。

这个问题的目的是改进我的这个问题,我喜欢这个问题,因为它被接受了,我觉得有一些性能可以从排序函数中挤出。我在这里问这个问题,因为我没有多少线索可以从哪里开始。
也许这也让事情变得更清楚了

更新 我重新表述了整个问题,因为很多人说我不够具体,我尽了最大的努力来说明我的意思。另外,我重写了
sort
函数,以便更好地表达问题的意图

  • 设arrayPrev为数组(A),其中A由0到n个元素组成(E)
    • 让一个元素
      • 原始类型的
        • 布尔值、字符串、数字、未定义、空
      • 对对象O的引用,其中O.type=[Object Object]和O可以由
        • 0到n属性P,其中P的定义类似于元素加号
          • O中任意P的循环引用
        • 其中任意O可以包含1到n次。在GetReferenceName(E1)==GetReferenceName(E2)的意义上
      • 对O的引用,其中O.type=[object Array]和O的定义类似于
      • 一种循环引用,用于引用
  • 设arrayCurr是与arrayPrev长度相同的数组
如下面的示例所示

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进行排序,使得对对象或原语值的任何引用,通过相同的比较函数,排序,数组a,共享与前面a中完全相同的位置

就像上面的例子一样

由此产生的数组应符合规则

  • 让arrayPrev包含
    a
    的元素,arrayCurr包含
    b
  • 让arrayPrev按比较函数C排序
  • 让arrayCurr按相同的C排序。
    • 将arrayCur排序的结果设为,当访问位于位置n的arrayCur中的E时,设n例如为5
      • 如果E的类型是对象GetReferencedName(arrayCurr[n])==GetReferencedName(arrayPrev[n])
      • 如果E的类型是基元GetValue(arrayCurr[n])==GetValue(arrayPrev[n])
      • i、 e
        b[n]==a[n]
        e.g
        b[5]==a[5]
    • 这意味着所有元素都应该按类型分组,并且在这种情况下按值排序
    • 其中,对C中函数F的任何调用应至少在ES5之前实现,以便在不需要任何垫片的情况下提供兼容性
我目前的方法是在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;
        }

    }
功能sort3(当前、上一个){
变量权重={
“[对象未定义]”:6,
“[对象]”:5,
“[对象空]”:4,
“[对象字符串]”:3,
“[对象编号]”:2,
“[对象布尔]”:1
}
如果(上一个){//标记对象
对于(变量i=上一个长度,j,t;i>0;i--){
t=类型(j=上一个[i]);
如果(j!=null&&t==“对象”){
j、 _pos=i;
}否则,如果(t!=“对象”&&t!=“未定义”)中断;
}
}
当前分拣(分拣机);
如果(上一个){
对于(变量k=上一个长度,l,t;k>0;k--){
t=类型(l=上一个[k]);
如果(t==“对象”&&l!=null){
删除l.(u pos);
}否则,如果(t!=“对象”&&t!=“未定义”)中断;
}
}
返回货币;
功能分拣机(a、b){
var tStr=Object.prototype.toString
变量类型=[tStr.call(a),tStr.call(b)]
var-ret=[0,0];
如果(类型[0]==类型[1]&&types[0]===“[对象]”){
如果(上一个)返回a.\U位置-b.\U位置
否则{
返回a==b?0:1;
}
}else if(类型[0]!==类型[1]){
返回权重[类型[0]]-权重[类型[1]]
}

从描述中返回a>b?1:a,似乎您可以简单地使用排序函数:

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);
试试这个

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);

您的函数总是返回一个
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
    };

})();
var sort=(函数(){
var-tmp;
功能分拣机(a、b){
变量类型=[a的类型,b的类型];
if(类型[0]=“对象”&&types[1]=“对象”){
返回tmp.indexOf(a)-tmp.indexOf(b);//按原始位置排序
}
if(类型[0]=“对象”){
返回1;
}
如果(类型[1]=“对象”){
返回-1;
}
返回a>b1:a
请注意,我将
sort.el
替换为
tmp
和一个闭包。Fiddle:


编辑:此(以及您的原始解决方案)

  • 仅当数组包含相同的元素时才起作用
  • 维护
    a中不同对象的顺序
但是

  • 调用时不超过两次
    function strangeSort(curr, prev) {
        curr.length = 0;             // delete the contents of curr
        curr.push.apply(curr, prev); // append the contents of prev to curr
    }