简体   繁体   中英

Remove empty brackets from a JSON object

I would like to remove the matching elements {}, and {} from a JSON string.

Input : "test": [{},{},{},{},{},{},{}],

Output : "test": [],

To do so, I tried :

var jsonConfig = JSON.stringify(jsonObj);
var jsonFinal = jsonConfig.replace(/[{},]/g, ''); // Remove global
var jsonFinal = jsonConfig.replace(/[{},]/, ''); // Remove brackets

console.log(jsonFinal);

and many more.

How can I remove only those set of elements from my JSON without impacting the other brackets and comma?

Do NOT attempt to modify JSON with string manipulation functions.

ALWAYS parse the JSON, transform the data, and re- stringify to JSON.

EDIT: this answer addresses your comment that the input data object will contain other potential keys that should be present in the output.

// a couple of procedures to help us transform the data
const isEmptyObject = x => Object.keys(x).length === 0;
const not = x => ! x;
const comp = f => g => x => f (g (x));
const remove = f => xs => xs.filter (comp (not) (f));

// your input json
let json = '{"test": [{},{},{"x": 1}], "test2": [{},{}], "a": 1, "b": 2}';

// parsed json
let data = JSON.parse(json);

// transform data
let output = JSON.stringify(Object.assign({}, data, {

  // remove all empty objects from `test`
  test: remove (isEmptyObject) (data.test),

  // remove all empty objects from `test2`
  test2: remove (isEmptyObject) (data.test2),
}));

// display output
console.log(output); // '{"test":[{"x":1}],"test2":[],"a":1,"b":2}'

I like the ES2015 answer of @naomik.
This is another alternative:

/**
 * Remove empty objects or arrays
 * @param  {Object, Array} obj: the object to which remove empty objects or arrays
 * @return {Any}
 */
const removeEmptyObject = (function() {
  const isNotObject = v => v === null || typeof v !== "object";
  const isEmpty = o => Object.keys(o).length === 0;

  return function(obj) {
    if (isNotObject(obj)) return obj;
    if (obj instanceof Array) {
      for (let i = 0; i < obj.length; i += 1) {
        if (isNotObject(obj[i])) continue;
        if (isEmpty(obj[i])) obj.splice(i--, 1);
        else obj[i] = removeEmptyObject(obj[i]);
      }
    }
    else {
      for (let p in obj) {
        if (isNotObject(obj[p])) continue;
        if (!isEmpty(obj[p])) obj[p] = removeEmptyObject(obj[p]);
        if (isEmpty(obj[p])) delete obj[p];
      }
    }
    return obj;
  }
}());

Now lets test the code:

var json = '{"test": [{},{},{"x": 1}], "test2": [{},{}], "test3":[[],[1,2,3],[]], "a": 1, "b": 2}';
var data = JSON.parse(json); //Object
var output = removeEmptyObject(data);

console.log(output);
console.log(removeEmptyObject(9));
console.log(removeEmptyObject(null));
console.log(removeEmptyObject({}));

You should work on the actual object not the string.

If you do, you can loop through the object and check if it has any properties. If it doesn't have any, you can remove it.

for(var prop in obj) {
    if (obj.hasOwnProperty(prop)) {
       //remove here
    }
}

Setting aside the question of whether string manipulation is the best way to tidy up JSON data, your earlier attempts would remove all braces and commas, because [] in a regexp indicates "match any of the characters contained inside these brackets". If you were trying to treat those as literal characters, they'd need to be escaped: \\[ or \\]

You want something like .replace(/{},?/g,"") (which means "match all instances of the string {} or the string {}, -- the question mark makes the preceding character an optional match).

(This would, of course, remove all empty objects from the string, and has the potential to create invalid JSON given input like "foo: {}, bar: {}" -- so only use this if you're certain that your data will never include intentionally empty objects.)

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