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