[英]Removing array elements when each element can reference an index in the array
{
"childA": 156,
"childB": 2422,
"color": "df7f00",
"id": 124,
"posA": {
"x": 5,
"y": -46,
"z": 11
},
"posB": {
"x": 5,
"y": -46,
"z": 11
},
"shapeId": "4a1b886b-913e-4aad-b5b6-6e41b0db23a6",
"xaxisA": 1,
"xaxisB": 1,
"zaxisA": 2,
"zaxisB": 2
}
首先是一些重要的背景 在JavaScript中使用數組。 所以我有一個帶有數組“body”的對象,其中包含一個“childs”數組。 上面張貼的代碼就是其中一個孩子。
現在我已經用.filter()方法編寫了一些javascript來刪除某些基於shapeId的子節點,但這會產生“childA”和“childB”值的問題,這些值指向childs數組中的某個索引。 值得注意的是,並非childs數組中的所有元素都具有子*屬性。 我很難想到如何完成刪除一個元素,然后修復“childA”,“childB”等等...在childs數組中的其他元素的值因此被拋出。
我想我需要在刪除元素之前檢查子元素,在刪除元素之后引用子元素並調整它,以及在引用子元素之前刪除元素之后的子元素。 我還需要刪除對從數組中刪除的元素的引用。 我不知道如何實現這一目標。
在我學習的時候請原諒我的無知,謝謝你的幫助。
這是最初幾個孩子的對象:
{
"bodies": [{
"childs": [{
"color": "560202",
"controller": {
"audioIndex": 1,
"controllers": null,
"id": 28253,
"joints": null,
"pitch": 1,
"volume": 100
},
"pos": {
"x": -13,
"y": -18,
"z": 3
},
"shapeId": "4c6e27a2-4c35-4df3-9794-5e206fef9012",
"xaxis": 2,
"zaxis": 1
}, {
"color": "0a1d5a",
"controller": {
"audioIndex": 1,
"controllers": null,
"id": 28248,
"joints": null,
"pitch": 1,
"volume": 100
},
"pos": {
"x": 16,
"y": -13,
"z": 3
},
"shapeId": "4c6e27a2-4c35-4df3-9794-5e206fef9012",
"xaxis": 1,
"zaxis": -2
},
就個人而言,我會避免直接使用索引,因為以可靠的方式讓它們保持最新是非常棘手的。 一種可能的替代方案是向對象添加一些“id”字段,因此可以獨立於數組上的位置訪問它; 你也可以有一個輔助對象,其中包含id作為鍵,對象引用自身作為值,以加快訪問速度。
數據結構的方式似乎不太適合編輯,因此如果意圖使得非常簡單,那么直接對原始結構進行操作只會是可行的。 對於更復雜的編輯,將其轉換為內部的,更方便的表示,在其上進行更改,然后將其轉換回原始表示,實際上可以節省調試頭痛的時間。
只是想發布我目前正在使用的代碼,這實際上是在游戲中提供有效的藍圖。 我希望對你自己的問題發表答案並不是不禮貌,但它現在正在運作,我很想分享它。 處理這個問題的方法可能更有效,但這就是我所擁有的:
function deleteObjects() {
var IdCleanup = new Array();
objectCount = 0;
var cleanupCount = 0;
var jointCleanupCount = 0;
var oChildIndex = 0;
var childACleanup = 0;
var childBCleanup = 0;
var childCCleanup = 0;
// Loop through the array manually and remove the id of elements being removed from thejson.bodies[i].childs[j].controller.controllers[*].id
// fruits.splice(index, howmany);
/* for(var i = 0; i < thejson.bodies.length; i++) { thejson.bodies[i].childs = thejson.bodies[i].childs.filter(checkObject); } */
/***************************************************************************************************************
To do list:
1. Add thejson.bodies[*].childs[*].controller.id to IdCleanup list.
2. Remove thejson.bodies[*].childs[*]
3. Adjust thejson.joints[*].childA, thejson.joints[*].childB, .... references.
4. Remove thejson.bodies[*].childs[*].controller.controllers[*].id values in the IdCleanup list.
***************************************************************************************************************/
// One pass to delete the child objects, and add the deleted child's IDs to list.
for(var i = 0; i < thejson.bodies.length; i++) {
for(var j = 0; j < thejson.bodies[i].childs.length; j++) {
// Shape matches dropdown menu value.
if(thejson.bodies[i].childs[j].shapeId == document.getElementById("mySelect").value) {
if(IdCleanup.indexOf(thejson.bodies[i].childs[j].controller.id) == -1) {
// Add this ID to the list of ones to remove.
IdCleanup[IdCleanup.length] = thejson.bodies[i].childs[j].controller.id;
}
// Remove this child.
thejson.bodies[i].childs.splice(j, 1);
j--;
oChildIndex--;// Keeping the overall index accurate.
// Adjust joints array.
if(thejson.joints != undefined) {
for(var k = 0; k < thejson.joints.length; k++) {
if(thejson.joints[k].childA) {
var idx = thejson.joints[k].childA;
if(idx < oChildIndex) {
} else if(idx > oChildIndex) {
thejson.joints[k].childA--;
jointCleanupCount++;
childACleanup++;
} else if(idx == oChildIndex) {
}
}
if(thejson.joints[k].childB) {
var idx = thejson.joints[k].childB;
if(idx < oChildIndex) {
} else if(idx > oChildIndex) {
thejson.joints[k].childB--;
jointCleanupCount++;
childBCleanup++;
} else if(idx == oChildIndex) {
}
}
if(thejson.joints[k].childC) {
var idx = thejson.joints[k].childC;
if(idx < oChildIndex) {
} else if(idx > oChildIndex) {
thejson.joints[k].childC--;
jointCleanupCount++;
childCCleanup++;
} else if(idx == oChildIndex) {
}
}
}
}
objectCount++;
}
oChildIndex++;
}
}
// Second pass for cleaning up the IDs from thejson.bodies[i].childs[j].controller.controllers that need removed.
for(var i = 0; i < thejson.bodies.length; i++) {
for(var j = 0; j < thejson.bodies[i].childs.length; j++) {
var object = thejson.bodies[i].childs[j];
// Check for controllers
if(thejson.bodies[i].childs[j].controller && thejson.bodies[i].childs[j].controller.controllers != null) {
for(var k = 0; k < thejson.bodies[i].childs[j].controller.controllers.length; k++) {
if(IdCleanup.indexOf(thejson.bodies[i].childs[j].controller.controllers[k].id) != -1) {
// one of the controllers match an ID of one that was deleted.
var idx = IdCleanup.indexOf(thejson.bodies[i].childs[j].controller.controllers[k].id);
thejson.bodies[i].childs[j].controller.controllers.splice(k,1);
k--;
cleanupCount++;
}
}
}
}
}
var processLog = document.getElementById('processLog');
processLog.value = processLog.value +"\n"+ objectCount +" objects deleted.\n";
processLog.value = processLog.value + cleanupCount +" ID cleanup operations.\n";
processLog.value = processLog.value + jointCleanupCount +" joint cleanup operations.\n";
processLog.value = processLog.value + childACleanup +" A, "+ childBCleanup +" B, "+ childCCleanup +" C\n";
}
最初這只是一個遍歷body數組的循環,然后在每個子數組上使用.filter檢查相應的shapeId。 這導致關節數組(與body(&childs)數組分開)指向childs數組中的錯誤索引。 Haroldo_OK讓我走上正確的道路來解決這個問題。 幾分鍾前,當我要移除一個孩子時,我發現我的整體孩子數量(oChildCount:P)不准確。 因此,每次我移除一個孩子,我都會減少這個數量,瞧! 有用!
非常感謝,Haroldo_OK
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.