1

I've got a data array:

const data = [{
  name: 'South America',
  locations: [{
    name: 'Argentina',
    locations: [{
      name: 'Buenos Aires'
    }, {}]
  }]
}, {
  name: 'Europe',
  locations: [{
    name: 'Spain',
    locations: [{}]
  }]
}, {
  name: 'Asia',
  locations: [{}]
}]

I'd like to remove any empty objects on any level (even if it's really deep). Returning as the example below:

[{
  name: 'South America',
  locations: [{
    name: 'Argentina',
    locations: [{
      name: 'Buenos Aires'
    }]
  }]
}, {
  name: 'Europe',
  locations: [{
    name: 'Spain',
    locations: []
  }]
}, {
  name: 'Asia',
  locations: []
}]

The key locations could be anything else.

My solution is just partial as it only deletes the first level.

FAILED ATTEMPT

const result = data.filter(value => Object.keys(value).length !== 0)

I'd like this to be as dynamic as possible, without having to specify how nested will it be.

1
  • 1
    That's certainly a good first stab at it. Perhaps a recursive approach might get you there? Maybe this answer will give youba little inspiration stackoverflow.com/a/52205522/1878262 Commented Aug 2, 2021 at 20:33

2 Answers 2

1

You could use create a recursive function with reduce and a for...in loop and make it so that both empty objects in a array and as a object value are removed.

const data = [{"name":"South America","locations":[{"name":"Argentina","locations":[{"name":"Buenos Aires","foo":{}},{}]}]},{"name":"Europe","locations":[{"name":"Spain","locations":[{}]}]},{"name":"Asia","locations":[{}]}]

function removeEmpty(data) {
  return data.reduce((r, e) => {
    if (Object.keys(e).length) {
      const obj = {}

      for (let k in e) {
        if (Array.isArray(e[k])) {
          obj[k] = removeEmpty(e[k])
        } else if (typeof e[k] === 'object') {
          if (Object.keys(e[k]).length) {
            obj[k] = removeEmpty(e[k])
          }
        } else {
          obj[k] = e[k]
        }
      }

      r.push(obj)
    }

    return r;
  }, [])
}

console.log(removeEmpty(data))

Sign up to request clarification or add additional context in comments.

Comments

0

const data = [{
  name: 'South America',
  locations: [{
    name: 'Argentina',
    locations: [{
      name: 'Buenos Aires'
    }, {}]
  }]
}, {
  name: 'Europe',
  locations: [{
    name: 'Spain',
    locations: [{}]
  }]
}, {
  name: 'Asia',
  locations: [{}]
}]

const isArray = Array.isArray
const isObject = (any) => typeof any === 'object' && any !== null

function clear(obj) {
  (function recursive(any, remove) {
    if (isArray(any)) {
      for (let i = 0; i < any.length; ++i) {
        recursive(any[i], () => {
          any.splice(i--, 1)
        })
      }
    }
    else if (isObject(any)) {
      const values = Object.values(any)
      if (values.length) {
        for (let item of values) {
          recursive(item, () => null)
        }
      } else {
        remove() // <- delete {}
      }
    }
  })(obj, () => null)
}

// 
clear(data)
console.log(data)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.