Michael R Michael R - 6 months ago 22
JSON Question

Delete unmatching objects in nested array

I got problem to use the splice method in a generic way in a nested array.
So what I want is to delete objects in "bigArray"s "nestedArray"s if "filterArray" dosen´t have a reference for the object.

I´ve made an example of what I want to do.
If you guys got a solution on how I can improve it in native javascript or with Lodash feel free to give input. I'm really stuck.

Expected result should be:

sort.unsortedArray = { "bigArray" : [
{"id": 1, "text" : "This should be visible when done",
"nestedArray": [
{ "id": 2, "nestedText": "Sort me out!" }
]
},
{ "id": 2, "text" : "This should be visible when done",
"nestedArray": [
{ "id": 2, "nestedText": "This one should be visible in the coming array" }
]
}]}


Here´s a codepen for it.

var sort = this;
var init = function(){
sort.outObjects();
};
sort.filterArray = { "filter" : [
{ "id": 3, "groupId": 1 },
{ "id": 2, "groupId": 2 }]};

sort.unsortedArray = { "bigArray" : [
{"id": 1, "text" : "This should be visible when done",
"nestedArray": [
{ "id": 1, "nestedText":"Sort this one out!" },
{ "id": 2, "nestedText": "Sort me out!" },
{ "id": 3, "nestedText": "This one should be visible in the coming array"}]},

{ "id": 2, "text" : "This should be visible when done",
"nestedArray": [
{ "id": 1, "nestedText": "Sort me out!" },
{ "id": 2, "nestedText": "This one should be visible in the coming array" },
{"id": 3, "nestedText": "Sort this one out!" }]}
]},

sort.outObjects = function (){

//Check that we got the objects in same scope
if(sort.filterArray && sort.unsortedArray){

//Loop through "bigArray" object
for( var i = 0; i< sort.unsortedArray.length; i++){

console.log("sort.unsortedArray.length : ", sort.unsortedArray.length);

//Loop through each "nestedArray":s objects
for( var j = 0; j< sort.unsortedArray[i].nestedArray.length; j++){
console.log("sort.unsortedArray[i].nestedArray.length : ", sort.unsortedArray[i].nestedArray.length);

//Loop through filterArray object and compare each object in nested array, if they dont match, delete them.

for( var k = 0; k< sort.filterArray.length; k++){
console.log("sort.filterArray.length : ", sort.filterArray.length);

if(sort.filterArray[k].id != sort.unsortedArray[i].nestedArray[j].id){

//Delete unmatching object from unsortedArray
sort.unsortedArray[i].nestedArray.splice(j,1);

console.log("sort.unsortedArray after splice : ", sort.unsortedArray);
}
}
}
}
}
else{
console.log("Missing connection to object",sort.filterArray, sort.unsortedArray);
}
}

init();

Answer

You could generate an object for faster access and test for the final filtering.

After generating it, you could iterate over the data, check if a change is necessary and apply filtering.

var filterArray = { "filter": [{ "id": 3, "groupId": 1 }, { "id": 2, "groupId": 2 }] },
    unsortedArray = { "bigArray": [{ "id": 1, "text": "This should be visible when done", "nestedArray": [{ "id": 1, "nestedText": "Sort this one out!" }, { "id": 2, "nestedText": "Sort me out!" }, { "id": 3, "nestedText": "This one should  be visible in the coming array" }] }, { "id": 2, "text": "This should be visible when done", "nestedArray": [{ "id": 1, "nestedText": "Sort me out!" }, { "id": 2, "nestedText": "This one should  be visible in the coming array" }, { "id": 3, "nestedText": "Sort this one out!" }] }] },
    filterObject = Object.create(null);

filterArray.filter.forEach(function (a) {
    filterObject[a.groupId] = a.id;
});

unsortedArray.bigArray.forEach(function (a) {
    if (a.id in filterObject) {
        a.nestedArray = a.nestedArray.filter(function (b) {
            return b.id === filterObject[a.id];
        });
    }
});

console.log(unsortedArray);

Comments