简体   繁体   中英

Javascript: Splice Multidimensional Object

I'm having this Object/Array Structure :

Obj = {
    "User": {
        "user1": [{
            "desc": "NG60",
            "Id": 3473631702,
            "Status": "offline"
        }],

        "user2": [{
            "desc": "somevalue",
            "Id": 963346121,
            "Status": "offline"
        },
        {
            "desc": "othervalue",  // SPLICE THIS OUT
            "Id": 963346122,      // SPLICE THIS OUT
            "Status": "offline"  // SPLICE THIS OUT
        }],

        "user3": [{
            "desc": "whatever",
            "Id": 972878784
        }]
    }
}

I want to filter out different values, dynamically (fixed in this example) and if there are no Ids left, I want to delete the whole user Array.

For example, if I want to filter out the 2nd Array Element of user2 :

 for(var users in Obj) {
     for(var Ids in Obj[users]) {
         if(Obj[users][Ids].Id == 963346122){
             Obj[users][Ids].splice(0, 1); // ERROR HERE
         }
     }
     if(Obj[users][Ids] == undefined) {
         delete Obj[users];
     }
 }

I get this Error:

User[users][Ids].splice(0, 1) is not a function

How to splice only the Array Element that I'm addressing, not the complete user2 Array?

Use array.prototye.filter to remove user from array and use delete to remove the whole user array in case there is no element left:

 var obj = { "User": { "user1": [ { "desc": "NG60", "Id": 3473631702, "Status": "offline" } ], "user2": [ { "desc": "somevalue", "Id": 963346121, "Status": "offline" }, { "desc": "othervalue", // SPLICE THIS OUT "Id": 963346122, // SPLICE THIS OUT "Status": "offline" // SPLICE THIS OUT } ], "user3": [ { "desc": "whatever", "Id": 972878784 } ] } }; function deleteUser(id) { Object.keys(obj.User).forEach(user => { obj.User[user] = obj.User[user].filter(u => u.Id !== id); if (obj.User[user].length === 0) { delete obj.User[user]; } }); } deleteUser(963346121); console.log(obj); deleteUser(972878784); console.log(obj); 

You have to use another for loop to wrap the actual operation because the length is not the same for all iterating objects. That's why you have to slice the object from the proper position.

Try the following:

 let Obj = { "User": { "user1": [ { "desc": "NG60", "Id": 3473631702, "Status": "offline" } ], "user2": [ { "desc": "somevalue", "Id": 963346121, "Status": "offline" }, { "desc": "othervalue", // SPLICE THIS OUT "Id": 963346122, // SPLICE THIS OUT "Status": "offline" // SPLICE THIS OUT } ], "user3": [ { "desc": "whatever", "Id": 972878784 } ] } } for(var users in Obj) { for(var Ids in Obj[users]) { for(var i=0; i<Obj[users][Ids].length;i++){ if(Obj[users][Ids][i].Id == 963346122){ Obj[users][Ids].splice(i, 1); // ERROR HERE } } } if(Obj[users][Ids] == undefined) { delete Obj[users]; } } console.log(Obj); 

Problem: the splice you used was pointing to string not Object/Array. Use delete rather than splice for Object removal.

Better for future filters:

//using same Obj:
for (i in Obj) {
    if (Obj.hasOwnProperty(i)) {
        var subObj = Obj[i];
        for (j in subObj) {
            var child = subObj[j];
            for (k in subObj[j]) {
                if(child[k].Id == 963346122){ //this user contains specified id the delete this user.
                    delete  child[k];
                }
            }
         }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM