我有一个对象数组,其中一些元素是另一个元素的克隆,因此它们具有一个引用原始元素另一个属性的属性(简化示例):
var a = [{
id: 'x0',
name: 'Foo',
isClone: false,
wasCloned: true,
originalId: ''
}, {
id: 'y1',
name: 'Bar'.
isClone: false,
wasCloned: false,
originalId: ''
}, {
id: 'z2',
name: 'Foo',
isClone: true,
wasCloned: false,
originalId: 'x0'
}];
在此示例中,第三个元素引用第一个元素的ID-从这个意义上讲,它使其成为一个克隆.不幸的是,id并不是增量/时间顺序的,基本上可以是任何随机字符串.
现在,当前的任务是以这种方式对阵列进行排序,以使克隆始终位于阵列位置上,而其位置恰好在其原始位置之前.如果数组元素不是克隆元素,则排序应照常进行.换句话说,一旦排序,该示例中的顺序将为2,0,1.
我试图弄清楚如何使用Array.sort,但是无法真正解决这个问题.这基本上是我所拥有的(不起作用):
var sortedA = a.sort(function(one, other) {
var sorted;
if (one.id == other.originalId) {
sorted = -1;
} else {
sorted = 0;
}
return sorted;
});
对此,我们将不胜感激,谢谢.
解决方法:
我的解决方案类似于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]);
}
我认为这为您提供了更大的灵活性,因为您现在有机会对阵列进行排序,而不必考虑克隆.另外,您还可以使用单独的排序功能对克隆进行排序.