简体   繁体   中英

javascript extract same values of keys from array of objects

I have hundreds of objects inside each other and under each object there is a repeated object structure with an object inside that contains hundred of keys that are the same and in most of the keys the values are the same also.

What I would like to do is to get from this repeated object the key and value only if its the same across all over the objects and put it aside in an new object that contains all the same repeated pairs of key/value while also remove it from that repeated object inside of every one of the objects.

json objects for example:

[{
    "name": "A",
    "values": {
        "ab": "abc",
        "ac": "1",
        "ad": "none"
    },
    "childs": []
},
{
    "name": "A",
    "values": {
        "ab": "abc",
        "ac": "1",
        "ad": "none"
    },
    "childs": [{
        "name": "B",
        "values": {
            "ab": "abc",
            "ac": "1",
            "ad": "none"
        },
        "childs": [{
                "name": "C",
                "values": {
                    "ab": "abc",
                    "ac": "1",
                    "ad": "none"
                },
                "childs": []
            },
            {
                "name": "C",
                "values": {
                    "ab": "def",
                    "ac": "1",
                    "ad": "none"
                },
                "childs": []
            }
        ]
    }]
},
{
    "name": "A",
    "values": {
        "ab": "abc",
        "ac": "1",
        "ad": "none"
    },
    "childs": [{
        "name": "D",
        "values": {
            "ab": "abc",
            "ac": "1",
            "ad": "none"
        },
        "childs": []
    }]
}]

desired output:

[{
    "name": "A",
    "values": {
        "ab": "abc"
    },
    "childs": []
},
{
    "name": "A",
    "values": {
        "ab": "abc"
    },
    "childs": [{
        "name": "B",
        "values": {
            "ab": "abc"
        },
        "childs": [{
                "name": "C",
                "values": {
                    "ab": "abc"
                },
                "childs": []
            },
            {
                "name": "C",
                "values": {
                    "ab": "def"
                },
                "childs": []
            }
        ]
    }]
},
{
    "name": "A",
    "values": {
        "ab": "abc"
    },
    "childs": [{
        "name": "D",
        "values": {
            "ab": "abc"
        },
        "childs": []
    }]
}]

and a new object contains the key/value pairs that were removed because they are the same:

[{
    "ac": "1",
    "ad": "none"
}]

We could take the first object as a starting point for key value pairs:

let pairs = Object.entries( objects[0].values );

Then for all the values we remove non dupes:

function remove(obj){
  pairs = pairs.filter(([key,value]) => obj.values[key] === value);
  //the same for all childs:
  if(obj.childs) obj.childs.forEach(remove);
}
objects.forEach(remove);

So now weve got a list of key values every object shares, so now we can build an object again:

const result = {};
for(let [key,value] of pairs) result[key] = value;

And we can remove duplicates:

function dupes(obj){
  pairs.forEach(([key]) => {
    if( key in obj.values) delete obj.values[key];
  });
  if(obj.childs) obj.childs.forEach(dupes);
}
objects.forEach(dupes)

Try it

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