Using JavaScript what's the quickest way to recursively remove properties and values from an object?

19,070

Solution 1

A simple self-calling function can do it.

function removeMeta(obj) {
  for(prop in obj) {
    if (prop === '$meta')
      delete obj[prop];
    else if (typeof obj[prop] === 'object')
      removeMeta(obj[prop]);
  }
}

var myObj = {
  "part_one": {
    "name": "My Name",
    "something": "123",
    "$meta": {
      "test": "test123"
    }
  },
  "part_two": [
    {
      "name": "name",
      "dob": "dob",
      "$meta": {
        "something": "else",
        "and": "more"
      }
    },
    {
      "name": "name",
      "dob": "dob"
    }
  ],
  "$meta": {
    "one": 1,
    "two": 2
  }
}

function removeMeta(obj) {
  for(prop in obj) {
    if (prop === '$meta')
      delete obj[prop];
    else if (typeof obj[prop] === 'object')
      removeMeta(obj[prop]);
  }
}

removeMeta(myObj);

console.log(myObj);

Solution 2

As @floor commented above:

JSON.parse(JSON.stringify(obj, (k,v) => (k === '$meta')? undefined : v))

Solution 3

// Helper function
function removeProps(obj,keys){
  if(Array.isArray(obj)){
    obj.forEach(function(item){
      removeProps(item,keys)
    });
  }
  else if(typeof obj === 'object' && obj != null){
    Object.getOwnPropertyNames(obj).forEach(function(key){
      if(keys.indexOf(key) !== -1)delete obj[key];
      else removeProps(obj[key],keys);
    });
  }
}
// The object we want to iterate
var obj = {
  "part_one": {
    "name": "My Name",
    "something": "123",
    "$meta": {
      "test": "test123"
    }
  },
  "part_two": [
    {
      "name": "name",
      "dob": "dob",
      "$meta": {
        "something": "else",
        "and": "more"
      }
    },
    {
      "name": "name",
      "dob": "dob"
    }
  ],
  "$meta": {
    "one": 1,
    "two": 2
  }
};
// Utilize the utility
removeProps(obj,['$meta']);
// Show the result
document.body.innerHTML = '<pre>' + JSON.stringify(obj,null,4) + '</pre>';

Solution 4

I created this functions when any key is in any level in the object using the reference function of @Joseph Marikle

const _ = require("lodash");
const isObject = obj => obj != null && obj.constructor.name === "Object";
const removeAttrDeep = (obj, key) => {
    for (prop in obj) {
      if (prop === key) delete obj[prop];
      else if (_.isArray(obj[prop])) {
        obj[prop] = obj[prop].filter(k => {
          return !_.isEmpty(removeAttrDeep(k, key));
        });
     } else if (isObject(obj[prop])) removeAttrDeep(obj[prop], key);
    }
    return obj;
 };

EXAMPLE:

 const _obj = {
       a: "b", b: "e", c: { a: "a", b: "b", c: "c"},
       d: [ { a: "3" }, { b: ["2", "3"] }]};
 console.log(removeAttrDeep(_obj, "b"));

Solution 5

(Apologies, I do not yet have enough reputation points to comment directly.)

Just FYI, typeof null === 'object', so in the removeMeta() example offered by @joseph-marikle, the function will recurse on a null value.

Read more here: why is typeof null "object"?

Share:
19,070

Related videos on Youtube

Leon Revill
Author by

Leon Revill

Mobile architect, hybrid app enthusiast, published author, blogger and web component advocate.

Updated on June 26, 2022

Comments

  • Leon Revill
    Leon Revill almost 2 years

    I need to find the fastest way to remove all $meta properties and their values from an object, for example:

    {
      "part_one": {
        "name": "My Name",
        "something": "123",
        "$meta": {
          "test": "test123"
        }
      },
      "part_two": [
        {
          "name": "name",
          "dob": "dob",
          "$meta": {
            "something": "else",
            "and": "more"
          }
        },
        {
          "name": "name",
          "dob": "dob"
        }
      ],
      "$meta": {
        "one": 1,
        "two": 2
      }
    }
    

    Should become the following given that the $meta property could be at any point in the object so some form of recursion will probably be needed.

    {
      "part_one": {
        "name": "My Name",
        "something": "123"
      },
      "part_two": [
        {
          "name": "name",
          "dob": "dob"
        },
        {
          "name": "name",
          "dob": "dob"
        }
      ]
    }
    

    Any help or advice would be greatly appreciated!

    Thank you!

    • floor
      floor almost 9 years
      Instead of using recursion, make a copy of the object omitting the properties and values you don't want. A general note about recursion in javascript: It depends on the browsers memory allocation which isn't much so recursion is resource heavy and won't work for large data sets unless careful memory management is implemented.
    • Joseph
      Joseph almost 9 years
      The fastest way is to implement it yourself first, then ask for help on making it faster.
    • floor
      floor almost 9 years
      You can can traverse an object properties and values with the use of a for in loop or better said for of --> developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
  • Rene Wooller
    Rene Wooller over 7 years
    until JS has tail recursion optimization this is not safe for large objects. It's also unsafe for objects with circular references.
  • Antti Haapala -- Слава Україні
    Antti Haapala -- Слава Україні over 7 years
    Rather, provide the replacer as an argument to the stringify call, thus avoiding serializing these properties into string to begin with
  • Maxime Lafarie
    Maxime Lafarie almost 7 years
    Smart way to achieve that in pure js at any level, thank you!
  • Cattani Simone
    Cattani Simone over 4 years
    works perfectly, just be sure to clone the object if you need to preserve the original one.
  • Coder
    Coder over 4 years
    I don't see it working for me. This takes just the first property if that's an object. What about the others? It will not return me the whole object with eliminating that particular prop. Or where am I missing?
  • Alex Alonso
    Alex Alonso almost 3 years
    Warning that this method will remove unserializable content from the object, like functions or DOM elements, for example
  • Codigo Morsa
    Codigo Morsa over 2 years
    It worked!, thanks.