Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/403.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.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中对具有特定异常的对象数组进行排序_Javascript_Arrays_Algorithm_Sorting - Fatal编程技术网

在Javascript中对具有特定异常的对象数组进行排序

在Javascript中对具有特定异常的对象数组进行排序,javascript,arrays,algorithm,sorting,Javascript,Arrays,Algorithm,Sorting,我有一个对象数组,其中一些元素是另一个元素的克隆,因此它们有一个引用原始元素另一个属性的属性(简化示例): 在本例中,第三个元素引用了第一个元素的id,从这个意义上说,它是一个克隆。不幸的是,id不是递增/按时间顺序排列的,基本上可以是任何随机字符串 现在,手头的任务是以这样一种方式对数组进行排序,使克隆始终位于数组位置的正前方。如果数组元素不是克隆,则应按常规进行排序。换句话说,一旦排序,本例中的顺序将为2,0,1 我试图弄清楚如何使用Array.sort来实现这一点,但我实在想不起来。这基本

我有一个对象数组,其中一些元素是另一个元素的克隆,因此它们有一个引用原始元素另一个属性的属性(简化示例):

在本例中,第三个元素引用了第一个元素的id,从这个意义上说,它是一个克隆。不幸的是,id不是递增/按时间顺序排列的,基本上可以是任何随机字符串

现在,手头的任务是以这样一种方式对数组进行排序,使克隆始终位于数组位置的正前方。如果数组元素不是克隆,则应按常规进行排序。换句话说,一旦排序,本例中的顺序将为2,0,1

我试图弄清楚如何使用
Array.sort
来实现这一点,但我实在想不起来。这基本上就是我得到的(不起作用):


非常感谢您提供的任何帮助。

您应该使用以下排序功能:

var sorted = a.sort(
    function (a, b) {
        var compareA = a.originalId || a.id;
        var compareB = b.originalId || b.id;

        if (compareA < compareB) {
            return -1;
        } else if (compareA > compareB) {
            return 1;
        } else {
            return a.originalId !== '' ? -1 : 1;
        }
    }
);
var sorted=a.sort(
功能(a、b){
var compareA=a.originalId | | a.id;
var compareB=b.originalId | | b.id;
if(compareAcompareB){
返回1;
}否则{
返回a.originalId!=''?-1:1;
}
}
);
函数工作的一个示例是可用的

  • 获取具有原始ID的所有对象,并保存没有原始ID的对象

    var others = [];
    var data = a.filter(function(elem) {
        if (elem.originalID !== '') {
            return true;
        } else {
            others.push(elem); // keep a trace of elements without originalID
            return false;
        }    
    });
    
  • 对它们进行分类,以便它们都打包在一起

    data.sort(function(a, b) {
        return a.originalID.localeCompare(b.originalID); //compare string
    });
    
  • 现在,所有具有相同
    originalID
    的元素都打包在一起了。 然后,我们只需要将具有良好
    id
    的元素添加到具有相同
    originalID
    的每个打包元素的末尾

    var originId = data[0].originalID; //get the first origin id
    for(var i = 0; i < data.length; i++) {
       var elem = data[i];
       //the end of a packed list
       if(originID !== elem.originalID) {
           var val = others.find(function(e, index) { //find the element with the good id
               if(return e.id === originID) {
                   others.splice(index, 1);//remove the element from the others array
                   return true;
               } else {
                   return false;
               }
           });
    
           data.splice(i, 0, val[0]); //insert it at the end of the packed list
           originID = elem.originalID; //save for next loop
       }
    }
    
    
    
    //just need to add the remaing element to the list
    var final = data.concat(others);
    console.log(final);
    
    var originId=data[0]。originalID//获取第一个源id
    对于(变量i=0;i

    它当然可以改进(增加检查,减少工作量),但我想你已经想到了。

    我的解决方案与GreenLeaf的类似。它将创建一个新数组,而不会修改原始数组,这对您来说可能是问题,也可能不是问题

    方法是首先删除克隆。然后,如果需要,可以对数组进行排序,最后将克隆插入其原始对象上方:

    // create a new array without any clones, save the clones 
    var clonesMap = {};
    var aWithoutClones = a.filter(function(item){
        if (item.isClone) {
            if (!clonesMap[item.originalId]) {
                clonesMap[item.originalId] = [];
            }
            clonesMap[item.originalId].push(item);
            return false;
        }
    
        return true;
    });
    
    // here you can sort aWithoutClones
    
    // put all clones back before their original object
    a = [];
    for (var i = 0; i < aWithoutClones.length; i++) {
        var currId = aWithoutClones[i].id;
        if (clonesMap[currId]){
            a = a.concat(clonesMap[currId]);
        }
        a.push(aWithoutClones[i]);
    }
    
    //创建一个没有任何克隆的新阵列,保存克隆
    var clonesMap={};
    var aWithoutClones=a.filter(函数(项){
    如果(项目isClone){
    如果(!clonesMap[item.originalId]){
    clonesMap[item.originalId]=[];
    }
    克隆映射[item.originalId].push(item);
    返回false;
    }
    返回true;
    });
    //在这里,您可以在没有克隆的情况下对A进行排序
    //将所有克隆放回其原始对象之前
    a=[];
    对于(var i=0;i

    我认为这给了你更多的灵活性,因为你现在有机会在不考虑克隆的情况下对数组进行排序。此外,您还可以使用单独的排序功能对克隆进行排序。

    这样您就不想更改该数组中原始项的顺序了?然后我认为“排序”不是一种方法(因为当你“排序”整个数组时,你很难保持顺序),而是要构建一个新数组。你还需要将
    one.originalId
    other.id
    进行比较。那么,你想按什么对原始数组进行排序?返回
    1
    怎么样?通常负(
    -1
    )浮到顶部,正(
    +1
    )沉到底部,相同(
    0
    )在排序时保持在原来的位置。一个对象可以有多少个克隆?+1是正确的解决方案,但最好给出一个解释。请注意,我相信这种字符串比较很不幸不会起作用,因为id/originalIds不能保证按时间顺序排列。。。正确的?让我更深入地理解了排序函数的功能,谢谢@安德烈亚斯博曼:嗯,你想按ID排序,不是吗?太好了,这就做到了,对我来说是最理想的,因为它只允许我以方便的方式保存克隆供以后使用。非常感谢!
    var originId = data[0].originalID; //get the first origin id
    for(var i = 0; i < data.length; i++) {
       var elem = data[i];
       //the end of a packed list
       if(originID !== elem.originalID) {
           var val = others.find(function(e, index) { //find the element with the good id
               if(return e.id === originID) {
                   others.splice(index, 1);//remove the element from the others array
                   return true;
               } else {
                   return false;
               }
           });
    
           data.splice(i, 0, val[0]); //insert it at the end of the packed list
           originID = elem.originalID; //save for next loop
       }
    }
    
    
    
    //just need to add the remaing element to the list
    var final = data.concat(others);
    console.log(final);
    
    // create a new array without any clones, save the clones 
    var clonesMap = {};
    var aWithoutClones = a.filter(function(item){
        if (item.isClone) {
            if (!clonesMap[item.originalId]) {
                clonesMap[item.originalId] = [];
            }
            clonesMap[item.originalId].push(item);
            return false;
        }
    
        return true;
    });
    
    // here you can sort aWithoutClones
    
    // put all clones back before their original object
    a = [];
    for (var i = 0; i < aWithoutClones.length; i++) {
        var currId = aWithoutClones[i].id;
        if (clonesMap[currId]){
            a = a.concat(clonesMap[currId]);
        }
        a.push(aWithoutClones[i]);
    }