简体   繁体   中英

Dynamically delete empty keys in complex JSON data (using vanilla JavaScript)

I have tried many different ways to parse and delete keys with empty values dynamically from a JSON file, using only JavaScript.

As of now, I have been able to delete keys that are not nested, with the exception of empty strings with a length greater than 0.

My main ask is how to access subvalues, evaluating the nested keys and deleting only the nested key - right now I end up deleting the root key.

Pardon if this is a duplicated question, but I could not find any implementation for this particular case that worked for me here or elsewhere.

Here is what I have so far:

 //DATA let input = '{"first_name": "","last_name": "Smith","email":"jane.smith@wyng.com","gender": null,"invitations": [{"from": "test","code": ""}],"company": {"name": "dds","industries": [""]},"address": {"city": "New York","state": "NY","zip": "10011","street": " "},"new Value": ""}'; //MAIN FUNCTION function removeEmptyFields(inputJSON) { let data = JSON.parse(inputJSON); //accessing top level keys (case1) for (let key in data) { let item = data[key]; //dig deeper if value not at top level if (item !== null && typeof item !== 'object') { deleteRecord(item) } else { lookDeeper(item) } if (item === null && typeof item === 'object') { deleteRecord(item) } //function that deletes empty records function deleteRecord(item) { // console.log(item + "#");//function that deletes empty records if (item === null || item === undefined || item.length === 0) { delete data[key]; } } //function to access values nested one level (case2) function lookDeeper(key) { if (typeof key === 'object' && typeof key != null) { for (let key2 in key) { if (typeof key[key2] === 'object' && typeof key[key2] != null) { console.log() for (let subItem in key[key2]) { // deleteRecord(key2[subItem]) } } deleteRecord(item[key2]) lookDeeper(item[key2]); } } } } return data; } let output = removeEmptyFields(input) console.log(output); //CASES: //1-> flat object: //data[key] //2 -> array/object //data[key][array-index] //3 ->object/object //data[key][subkey] //4 ->object/object/array //data[key][subkey][array-index] // Test cases in order, and delete nulls at the very end. return data as result 

Youre actually quite close, if you fix the recursive call and remove all the unneccessary you end up with:

function cleanUp(obj) {
  for(const key in obj) {
    const value = obj[key];
    if(typeof value === "object") {
      cleanUp(value);
    } else if(!value && value !== 0) {
      delete obj[key];
    }
  }
}

let output = JSON.parse(input);
cleanUp(output);

Found a way to do it. Thanks to everyone who contributed:

//DATA
let input = '{"first_name": "","last_name": "Smith","email":"jane.smith@wyng.com","gender": null,"invitations": [{"from": "test","code": ""}],"company": {"name": "dds","industries": [""]},"address": {"city": "New York","state": "NY","zip": "10011","street": " "},"new Value": ""}';




function isEmpty(value) {
    if (value === null)
        return true;

    if (typeof value == 'object' && Object.keys(value).length === 0)
        return true;

    if (typeof value == 'string' && value.trim() == '')
        return true;

    return false;
}

function removeEmptyFields(input) {
    if (Array.isArray(input)) {
        for (var index = input.length - 1; index >= 0; index--) {
            if (typeof input[index] == 'object') {
                removeEmptyFields(input[index]);
            }
            if (isEmpty(input[index])) {
                input.splice(index, 1);
            }
        }
    } else {
        for (var index in input) {
            if (typeof input[index] == 'object') {
                removeEmptyFields(input[index]);
            }
            if (isEmpty(input[index])) {
                delete input[index];
            }

        }

    }
    return input
}
let input = '{"first_name": "","last_name": "Smith","email":"jane.smith@wyng.com","gender": null,"invitations": [{"from": "test","code": ""}],"company": {"name": "dds","industries": [""]},"address": {"city": "New York","state": "NY","zip": "10011","street": " "},"new Value": ""}'

let objTest = JSON.parse( input )

console.dir( objTest )
purge( objTest )
console.dir( objTest )

/* purge recursively removes empty values from an object
  @param obj the object to purge
  @returns true if the object is an empty value
  */
function purge ( obj ) {
  switch ( true ) {
  case obj === null:
  case typeof obj === 'undefined':
  case typeof obj === 'string' && obj.trim() === '':
    return true

  case Array.isArray( obj ):
    for ( let i = obj.length - 1; i >= 0; i-- ) {
      if ( purge( obj[i] ) ) obj.splice( i, 1 )
    }
    return obj.length === 0

  case typeof obj === 'object':
    Object.keys( obj ).forEach( ( key ) => {
      if ( purge( obj[key] ) ) delete obj[key]
    } )
    return Object.keys( obj ).length === 0

  default:
    return false
  }
}

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