简体   繁体   中英

Filtering a nested Object based on keys which match values in an array

I'm having difficulties filtering keys of a nested Object based on another array, while retaining the original Object structure.

Input:

data = [
          {0: { key: "A", values: { 0: {g1: 0, g2: 0, g3: 0, g4: 0}}}},
          {1: { key: "B", values: { 0: {g2: 0, g3: 0, g5: 0}}}}
       ]

arr = [g1, g2, g3]

Expected Output:

data = [
          {0: { key: "A", values: { 0: {g1: 0, g2: 0, g3: 0}}}},
          {1: { key: "B", values: { 0: {g2: 0, g3: 0}}}}
       ]

What i have done so far:

data.forEach(function(e,i) {
    r = Object.keys(e[i].values[0]).filter(d => arr.includes(d))
    console.log(r)
})

This correctly prints [g1,g2,g3] and [g2,g3], but i want to retain the original Object structure, and not just have a list of the common keys.

This code does what you want. Reduce the array r to an object and assign it to the original object.

 var data = [ {0: { key: "A", values: { 0: {g1: 0, g2: 0, g3: 0, g4: 0}}}}, {1: { key: "B", values: { 0: {g2: 0, g3: 0, g5: 0}}}} ] var arr = ["g1", "g2", "g3"] var output = data.map(function(e,i) { var r = Object.keys(e[i].values[0]).filter(d => arr.includes(d)); var values = r.reduce((obj,key)=>{obj[key] = 0 ; return obj;},{}); var obj = {}; obj[i] = Object.assign(e[i],{values:{0:values}}) console.log(obj); return obj; }) console.log(output); 

Actually it is not much better than rebuilding the output object from scratch

 var data = [ {0: { key: "A", values: { 0: {g1: 0, g2: 0, g3: 0, g4: 0}}}}, {1: { key: "B", values: { 0: {g2: 0, g3: 0, g5: 0}}}} ] var arr = ["g1", "g2", "g3"] var output = data.map(function(e,i) { var obj = {}; obj[i] = {key : e[i].key, values : {0:{}}}; arr.forEach((ele)=>{ if(e[i].values[0][ele] != undefined) { obj[i].values[0][ele] = e[i].values[0][ele]; } }); console.log(obj); return obj; }) console.log(output); 

Perhaps something like this would do the trick, assuming your data object is true to form (explanation is included as code comments).

 function pruneObject(object, desiredKeys) { Object.keys(object) .filter(key => !desiredKeys.includes(key)) //Ignore desired keys .forEach(key => delete object[key]) //Remove the leftovers } var data = [{ 0: { key: "A", values: { 0: { g1: 0, g2: 0, g3: 0, g4: 0 } } } }, { 1: { key: "B", values: { 0: { g2: 0, g3: 0, g5: 0 } } } } ]; var arr = ['g1', 'g2', 'g3']; data.forEach((item,index) => pruneObject(item[index].values[0], arr)); //Prune each "values" object console.log(data); 

Note: This modifies the original object, although if necessary I could write an alternative solution to preserve it and return a new object instead.

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