[英]Sorting an array of objects with specific exceptions in Javascript
我有一個對象數組,其中一些元素是另一個元素的克隆,因此它們有一個屬性引用原始的另一個屬性(簡化示例):
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;
});
對此有任何幫助將不勝感激,謝謝。
您應該使用以下排序功能:
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;
}
}
);
此處提供了功能工作的示例。
獲取具有原始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
的元素打包在一起。 然后我們只需要在每個打包元素的末尾添加具有相同originalID
的良好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);
它確實可以改進(添加支票,減少工作量),但我認為你有了這個想法。
我的解決方案與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]);
}
我認為這為您提供了更大的靈活性,因為您現在有機會對數組進行排序而無需考慮克隆。 此外,您還可以使用單獨的排序功能對克隆進行排序。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.