alexmngn
alexmngn

Reputation: 9597

How to remove all instances of a specific key in an object?

I have a large javascript object which contains multiple instances of a key. I'd like to remove all instances of this key and value from the object.

I have this function which allows me to find a nested object, though I'm not sure how to modify it to get all objects, and to delete the keys from the object. Can someone help me with this?

var findObjectByKey= function (o, key) {
  if (!o || (typeof o === 'string')) {
    return null
  }
  if (o[key]) {
    return o[key];
  }

  for (var i in o) {
    if (o.hasOwnProperty(i)) {
      var found = findObjectByKey(o[i], key)
      if (found) {
        return found
      }
    }
  }
  return null
}

This is an example object where I'd like to remove all keys d:

var a = {
  b: {
    c: {
      d: 'Hello',
    },
    d: 'Hola',
    e: {
      f: {
        d: 'Hey'
      }
    }
  }
}

// To become
var a = {
  b: {
    c: {},
    e: {
      f: {}
    }
  }
}

Also, is there a way we could do this with Ramda by chance?

Upvotes: 0

Views: 2178

Answers (2)

Ori Drori
Ori Drori

Reputation: 191986

Using R.when, if o is an object, apply R.pipe to it. In the pipe, remove the property from the object using R.dissoc. Iterate other properties with R.map, and try to remove the property for each of them.

const removePropDeep = R.curry((prop, o) => R.when(
  R.is(Object),
  R.pipe(
    R.dissoc(prop),
    R.map(removePropDeep(prop))
  ),
  o
))

const a = {
  b: {
    c: {
      d: 'Hello',
    },
    d: 'Hola',
    e: {
      f: {
        d: 'Hey'
      }
    }
  }
}

const result = removePropDeep('d')(a)

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>

Upvotes: 3

Mark
Mark

Reputation: 92440

To alter the object in place you can just change:

return o[key];

to:

delete o[key];

To return a new object, make a new object with Object.assign(), then delete the key in question. Then recurse on the rest of the keys:

var a = {
  b: {
    c: {
      d: 'Hello',
    },
    d: 'Hola',
    e: {
      f: {
        d: 'Hey'
      }
    }
  }
}

var findObjectByKey= function (o, key) {
  if (!o || (typeof o === 'string')) {    //  assumes all leaves will be strings
    return o
  }
  o = Object.assign({}, o)                // make a shallow copy
  if (o[key]) {
    delete o[key]                         // delete key if found
  }
  Object.keys(o).forEach( k => {
      o[k] = findObjectByKey(o[k], key)   // do the same for children
    })
  return o                                // return the new object
}

let obj = findObjectByKey(a, 'd')
console.log(obj)

Upvotes: 1

Related Questions