0

{
        "1": {
            "0": [
                7606,
                7615,
                7596,
                7513,
                7514,
                7597,
                7605,
                7607,
                7608,
                7595
            ],
            "87": [
                7514,
                7605,
                7644,
                7607,
                7608
            ]
        },
         "2": {
            "0": [
                7573,
                7605,
                7572,
                7569
            ]
         },
         "3": { ....

}

I have this Following demo Json array . Note - There can be other objects too inside 1 or 2...

I need to remove the value of the array element which contains any value which matched in a given array [7605,7608,7615,7573]. I need to remove all these values form the above json array .

How can i recursively traverse the following array and remove all these values from the leaf array of the object .

For the above input the output should be

{
        "1": {
            "0": [
                7606,
                7596,
                7513,
                7514,
                7597,
                7607,
                7595
            ],
            "87": [
                7514,
                7644,
                7607
            ]
        },
         "2": {
            "0": [
                7568,
                7572,
                7569
            ]
         }
}

I tried using Object.keys but i am confused with the dynamic nature of the json.

INFOSYS
  • 1,465
  • 9
  • 23
  • 50
  • 2
    JSON is a *textual notation* for data exchange. [(More here.)](http://stackoverflow.com/a/2904181/157247) If you're dealing with JavaScript source code, and not dealing with a *string*, you're not dealing with JSON. – T.J. Crowder Sep 25 '17 at 08:26
  • Where specifically are you stuck? What has your research turned up? A thorough [search](/help/searching) here on SO should turn up the things you need to do this. – T.J. Crowder Sep 25 '17 at 08:27
  • Just to make things clearer, can any number inside your object be an array of other numbers? I mean, for example, can the value 7568 that is in `obj['2']['0']` be an array of other numbers? that is `obj['2']['0']['7568']` be an array of numbers. is your structure dynamic or static – Ammar Sep 25 '17 at 08:29
  • Show us the code of what you have tried. – Znaneswar Sep 25 '17 at 08:30
  • 7568 is static but the json key and values can be dynamic – INFOSYS Sep 25 '17 at 08:31

2 Answers2

2

You are correct in noting that Object.keys() is helpful in implementing a solution for a dynamic object such as this, but here's a possible recursive implementation employing the use of Object.entries() instead:

function filterObject(o, v) {
  return Object
    .entries(o).map(([key, value]) => {
      if (Array.isArray(value)) {
        value = value.filter(n => !v.includes(n))
      } else {
        value = filterObject(value, v)
      }

      return [key, value]
    })
    .reduce((o, [key, value]) => {
      return Object.assign(o, {
        [key]: value
      })
    }, {})
}

console.log(filterObject({
  "1": {
    "0": [
      7606,
      7615,
      7596,
      7513,
      7514,
      7597,
      7605,
      7607,
      7608,
      7595
    ],
    "87": [
      7514,
      7605,
      7644,
      7607,
      7608
    ]
  },
  "2": {
    "0": [
      7573,
      7605,
      7572,
      7569
    ]
  }
}, [7605, 7608, 7615, 7573]))

MDN's polyfills for various functions:

Patrick Roberts
  • 49,224
  • 10
  • 102
  • 153
  • @INFOSYS No problem. If you'd like clarifications of anything, just leave a comment here with any specific questions you have and I'll update my answer to address them. – Patrick Roberts Sep 25 '17 at 08:53
  • the only issue i have is i am using `node 0.10.24` for production and guess both object.keys and assign might not work i need to use underscore for that i guess – INFOSYS Sep 25 '17 at 08:55
  • @INFOSYS for backwards compatibility, you can use babel to compile any JavaScript versions or even some non-standard language extensions like React's JSX, into compliant ES5 equivalent code, which is capable of running on even IE8 in many cases. However, `Object.keys()` _should_ already exist in node v0.10, if I am not mistaken. – Patrick Roberts Sep 25 '17 at 08:58
  • @INFOSYS I've also added MDN links to suggested polyfills for those functions, should you be interested. – Patrick Roberts Sep 25 '17 at 09:02
1

You can use filter method which accepts a callback function in combination with Object.keys method.

The forEach() method executes a provided function once for each array element.

The indexOf() is used in order to returns the first index at which a given element can be found in the array, or -1 if it is not present.

The filter method creates a new array with all elements that pass the test implemented by the provided function.

forEach is used in order to iterating the object keys, then use filter method in order to remove items from array(those items which also exists in the given array [7605,7608,7615,7573]).

Also you can use includes method in order to check the presence of item in a given array.

json[key][subkey]=json[key][subkey].filter(function(item){
  return !array.includes(item);
});

let array=[7605,7608,7615,7573];
let json={
        "1": {
            "0": [
                7606,
                7615,
                7596,
                7513,
                7514,
                7597,
                7605,
                7607,
                7608,
                7595
            ],
            "87": [
                7514,
                7605,
                7644,
                7607,
                7608
            ]
        },
         "2": {
            "0": [
                7573,
                7605,
                7572,
                7569
            ]
         }
}
Object.keys(json).forEach(function(key){
  Object.keys(json[key]).forEach(function(subkey){
    json[key][subkey]=json[key][subkey].filter(function(item){
      return array.indexOf(item)==-1;
    });
  });
});
console.log(json);
Craig Ayre
  • 1,133
  • 9
  • 12
Mihai Alexandru-Ionut
  • 47,092
  • 13
  • 101
  • 128