簡體   English   中英

當每個元素可以引用數組中的索引時,刪除數組元素

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM