当每个元素可以引用数组中的索引时,删除数组元素

时间:2016-10-10 16:44:03

标签: javascript arrays

{
    "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数组中的所有元素都具有子*属性。我正在思考如何完成删除一个元素,然后修复“childA”,“childB”等等......很难在childs数组中将其他元素的值作为结果抛出。< / p>

我想我需要在删除元素之前检查子元素,并在删除元素之后引用子元素并调整它,以及在引用子元素之前删除元素之后的子元素。我还需要删除对从数组中删除的元素的引用。我不知道如何实现这一目标。

在我学习的时候请原谅我的无知,谢谢你的帮助。

这是前几个孩子的对象:

{
"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
    },

2 个答案:

答案 0 :(得分:0)

就个人而言,我会避免直接使用索引,因为以可靠的方式让它们保持最新状态可能会非常棘手;一种可能的替代方案是向对象添加一些“id”字段,因此可以独立于数组上的位置访问它;你也可以有一个辅助对象,其中包含id作为键,对象引用自己作为值,以加快访问速度。

数据的结构方式似乎不太适合编辑,因此如果意图使得非常简单,那么直接对原始结构进行操作只会是可行的。对于更复杂的编辑,将其转换为内部的,更方便的表示,在其上进行更改,然后将其转换回原始表示,实际上可以节省调试头痛的时间。

答案 1 :(得分:0)

只想发布我目前正在使用的代码,这实际上是在游戏中提供有效的蓝图。我希望对你自己的问题发表答案并不是不礼貌,但它现在正在运作,我渴望分享它。可能有更有效的方法来处理这个问题,但这就是我所拥有的:

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。这导致关节数组(与主体(&amp; childs)数组分开)指向子数组中的错误索引。 Haroldo_OK让我走上正确的道路来解决这个问题。几分钟前,当我要移除一个孩子时,我不能确保我的整体孩子数量(oChildCount:P)准确无误。因此,每次我移除一个孩子,我都会减少这个数量,瞧!它有效!

非常感谢,Haroldo_OK