Print JSON format String


  • 0
    I

    @vinod23 Have you tested your solution? How come you are not increasing the indent when there is a { or }?


  • 1
    I

    @agrawalm So how did you do it in the interview?

    This is my solution I whipped up, it works for some simple cases, not sure if its acceptable though:

    def print_json(s):
        indent = 0
        curr_line = ''
        for char in s:
    	    if char == ',':
    		    print ' '*indent + curr_line + char
    		    curr_line = ''
    	    elif char == '[' or char == '{':
    		    if curr_line != '':
    			    print indent*' ' + curr_line
    			    curr_line = ''
    		    print indent*' ' + char
    		    indent += 4
    	    elif char == ']' or char == '}':
    		    if curr_line != '':
    			    print indent*' ' + curr_line
    			    curr_line = ''
    		    indent -= 4
    		    print indent*' ' + char
    	    else:
    		    curr_line += char

  • 0
    N

    JavaScript solution:

    function printJSON(str) {
        let spaces = [];
        let output = '';
    
        str.split('').forEach(char => {
            switch(char) {
                case '{':
                case '[':
                    spaces.push('    ');
                    output += char + '\n' + spaces.join('');
                    break;
                case '}':
                case ']':
                    spaces.pop();
                    output += '\n' + spaces.join('') + char;
                    break;
                case ',':
                    output += char + '\n' + spaces.join('');
                    break;
                default:
                    output += char;
                    break;
            }
        });
    
        console.log(output);
    }
    

  • 1
    B

    said in Print JSON format String:

    "{"id": "0001", "type": "donut","name": "Cake","ppu": 0.55, "batters":{"batter":[{ "id": "1001", "type": "Regular" },{ "id": "1002", "type": "Chocolate" }]},"topping":[{ "id": "5001", "type": "None" },{ "id": "5002", "type": "Glazed" }]}"

    Java Solution

     private static String generate(String jsonString) {
    	 StringBuilder builder = new StringBuilder();
    	 StringBuilder spaces = new StringBuilder();
    	 
    	 for (int i = 0; i < jsonString.length(); i ++) {
    		 char c = jsonString.charAt(i);
    		 switch (c) {
    		 	case '{' :
    		 		spaces.append(' ');
    		 		builder.append(c).append('\n').append(spaces);
    		 		break;
    		 	case '[' :
    		 		spaces.append('\t');
    		 		builder.append(c).append('\n').append(spaces);
    		 		break;
    		 	case ']' :
    		 		builder.append('\n').append(spaces).append(c);
    		 		spaces.deleteCharAt(spaces.length()-1);
    		 		break;
    		 	case '}' : 
    		 		spaces.deleteCharAt(spaces.length()-1);
    		 		builder.append('\n').append(spaces).append(c);
    		 		break;
    		 	case ',':
    		 		builder.append(c).append('\n').append(spaces);
    		 		break;
    		 	default :
    		 		builder.append(c);
    		 }
    	 }
    	 
    	 return builder.toString();
     }</code>

  • 3
    Y

    Here is my Java solution, not sure if it is accepted.

        public static void main(String[] args) {
            String json = "{\"id\": \"0001\", \"type\": \"donut\", \"name\": \"Cake\", \"ppu\": 0.55, \"batters\":{\"batter\":[{ \"id\": \"1001\", \"type\": \"Regular\" },{ \"id\": \"1002\", \"type\": \"Chocolate\" }]},\"topping\":[{ \"id\": \"5001\", \"type\": \"None\" },{ \"id\": \"5002\", \"type\": \"Glazed\" }]}";
            System.out.println(pretty(json));
        }       
    
        public static String pretty(String s) {
            StringBuilder sb = new StringBuilder();
            int indent = 0;
            char pre = 0;
            for (char c : s.toCharArray()) {
                if (Character.isWhitespace(c)) continue;
                if (c == ']' || c == '}') indent--;
                if (pre == '[' || pre == '{' || pre == ',' || c == ']' || c == '}') {
                    sb.append('\n');
                    for (int i = 0; i < indent; i++) sb.append("  ");
                }       
                sb.append(c);
                if (c == '[' || c == '{') indent++;
                pre = c;
            }       
            return sb.toString();
        }
    

    Here is the result from running the above code:

    {
      "id":"0001",
      "type":"donut",
      "name":"Cake",
      "ppu":0.55,
      "batters":{
        "batter":[
          {
            "id":"1001",
            "type":"Regular"
          },
          {
            "id":"1002",
            "type":"Chocolate"
          }
        ]
      },
      "topping":[
        {
          "id":"5001",
          "type":"None"
        },
        {
          "id":"5002",
          "type":"Glazed"
        }
      ]
    }
    

  • 0
    A

    said in Print JSON format String:

    "type": "donut",

    I think the condition to print a json object in multi-lines is ill-defined, sometimes the json object is defined printed as single line. While other times, the json object is printed as multiple lines. The feeling I got is that if the number of characters in json object is few enough to fit in one line, then print in one line, otherwise print as multiple lines.


  • 0
    A

    Shall we consider the corner case that the string contains character "[]{}"?


  • 1
    A

    Here is my solution in python. It also consider the situation when string contains special characters.

    
    
    def pretty_print(s):
        i, l = 0, len(s)
        line = ""
        n_indent = 0
        result = []
        while i < l:
            if s[i] in "[{":
                if line != "\t" * n_indent:
                    result.append(line)
                result.append("\t" * n_indent + s[i])
                n_indent += 1
                line = "\t" * n_indent
                i += 1
            elif s[i] == '"':
                tmp = '"'
                i += 1
                while i < l and s[i] != '"':
                    tmp += s[i]
                    i += 1
                tmp += s[i]
                line += tmp
                i += 1
            elif s[i] == ",":
                line += s[i]
                result.append(line)
                line = "\t" * n_indent
                i += 1
            elif s[i] in "]}":
                if line != "\t" * n_indent:
                    result.append(line)
                n_indent -= 1
                tmp = "\t" * n_indent + s[i]
                i += 1
                while i < l and s[i] == " ":
                    i += 1
                if i < l and s[i] == ",":
                    tmp += s[i]
                    i += 1
                result.append(tmp)
                line = "\t" * n_indent
            elif s[i] == " ":
                i += 1         
            else:
                line += s[i]
                i += 1
        return "\n".join(result)
    
    s = '{A:"B",C:{D:"E",F:{G:"test[",I:"J"}, Y:  "Z"}}'
    print pretty_print(s)
    
    #{
    #    A:"B",
    #    C:
    #    {
    #        D:"E",
    #        F:
    #        {
    #            G:"test[",
    #            I:"J"
    #        },
    #        Y:"Z"
    #    }
    #}
    
    s = '["foo", {"bar":["baz",null,1.0,2]}]'
    print pretty_print(s)
    
    #[
    #    "foo",
    #    {
    #        "bar":
    #        [
    #            "baz",
    #            null,
    #            1.0,
    #            2
    #        ]
    #    }
    #]
    print pretty_print(s)
    

  • 0
    E

    @yuxiangmusic I think your output has a problem: '{' and '[' should always occupy a new line, but in your output '{' and '[' could be in the same line as ':'.


  • 0
    Y

  • 0
    E

    @yuxiangmusic I was talking about this interview question. As is posted by @agrawalm at the beginning, '{' and '[' should always occupy a new line.


  • 0

    said in Print JSON format String:

    "{"id": "0001", "type": "donut","name": "Cake","ppu": 0.55, "batters":{"batter":[{ "id": "1001", "type": "Regular" },{ "id": "1002", "type": "Chocolate" }]},"topping":[{ "id": "5001", "type": "None" },{ "id": "5002", "type": "Glazed" }]}"

    public class Json{
        public static String jsonString(String str){
    	if(str == null || str.trim().isEmpty()){
    	    throw new IllegalArgumentException();
    	}
    	StringBuilder bldr = new StringBuilder();
    	int i = 0;
    	boolean inList = false;
    	int tc = -1;
    	while(i < str.length()){
    	    char c = str.charAt(i);
    	    switch(c){
    	    case '{':
    		bldr.append('\n');
    		if(!inList){
    		    tc++;
    		}
    		bldr.append(addTabs(tc));
    		bldr.append('{');
    		if(!inList){
    		    bldr.append('\n');
    		    tc++;
    		    bldr.append(addTabs(tc));
    		}
    		i++;
    		break;
    	    case '}':
    		if(inList){
    		    bldr.append('}');
    		    i++;
    		    if(i < str.length() && str.charAt(i) == ','){
    			bldr.append(',');
    			i++;
    		    }
    		}else{
    		    tc--;
    		    bldr.append(addTabs(tc));
    		    bldr.append('}');
    		    i++;
    		    if(i < str.length() && str.charAt(i) == ','){
    			bldr.append(',');
    			i++;
    		    }
    		    bldr.append('\n');
    		    tc--;
    		    bldr.append(addTabs(tc));
    		    
    		}
    		break;
    	    case']':
    		bldr.append('\n');
    		tc--;
    		bldr.append(addTabs(tc));
    		bldr.append(']');
    		inList = false;
    		bldr.append('\n');
    		tc--;
    		i++;
    		break;
    	    case ',':
    		bldr.append(',');
    		if(!inList){
    		    bldr.append('\n');
    		    bldr.append(addTabs(tc));
    		}
    		i++;
    		break;
    	    case'[':
    		bldr.append('\n');
    		tc++;
    		bldr.append(addTabs(tc));
    		bldr.append('[');
    		tc++;
    		bldr.append(addTabs(tc));
    		inList= true;
    		i++;
    		break;
    	    default:
    		bldr.append(c);
    		i++;
    		    
    	    }
    	}
    	return bldr.toString();
        }
    
        private static String addTabs(int tc) {
    	StringBuilder sb = new StringBuilder();
    	while(tc > 0){
    	    sb.append('\t');
    	    tc--;
    	}
    	return sb.toString();
        }
        
    
        
    }

  • 0

  • 0
    J

    An easy to understand Simple Recursive Java Solution:

    public class JsonFormatter {
    
        public String format(String input) {
            input = input.replaceAll("\\s", ""); //assumes that the values in the key:value 
                                                 //pairs are words and not sentences
            return format(input, 1);
        }
    
        private String format(String input, int count) {
            StringBuilder sb = new StringBuilder();
            sb.append("" + input.charAt(0) );
    
            for (int i = 1; i < input.length() - 1;) {
    
                sb.append('\n');
                int colonIndex = i + input.substring(i).indexOf(':');
                insertTab(sb, count);
                sb.append(input.substring(i, colonIndex + 1));
    
                int commaIndex = 
                        input.substring(colonIndex + 1).contains(",") 
                        ? input.substring(colonIndex).indexOf(',') 
                        : Integer.MAX_VALUE;
    
                if (input.charAt(colonIndex + 1) == '[') {
                    int closingBracketIndex = colonIndex + 1 + 
                            getClosingBracketIndex(input.substring(colonIndex + 1));
                    sb.append(processJsonArray(
                            input.substring(colonIndex + 1, closingBracketIndex + 1), 
                            count + 1)
                    );
                    i = closingBracketIndex + 1;
                    if (input.charAt(closingBracketIndex + 1) == ',') {
                        sb.append(',');
                        i++;
                    }
    
                } else if (input.charAt(colonIndex + 1) == '{') {
                    int endIndex = 
                            colonIndex + getEndIndex(input.substring(colonIndex + 1)) + 1;
                    sb.append(format(input.substring(colonIndex + 1, endIndex + 1), count + 1));
                    i = endIndex + 1;
    
                } else if (commaIndex == Integer.MAX_VALUE) {  
                    // no other commas, print the rest of the part
                    sb.append(input.substring(colonIndex + 1, input.length() - 1));
                    break;
    
                } else {
                    // the line ends with a comma
                    // print the rest of the line and update i , i.e, go to next line
                    sb.append(input.substring(colonIndex + 1, colonIndex + commaIndex + 1));
                    i = colonIndex +  commaIndex + 1;
                }
    
            } // end of for loop
    
            sb.append('\n');
            insertTab(sb, count - 1);
            sb.append(input.charAt(input.length() - 1));
            return sb.toString();
        }
    
        private void insertTab(StringBuilder sb, int count) {
            for (int i = 0; i < count; i++) {
                sb.append("\t");
            }
        }
    
        private int getClosingBracketIndex(String input) {
            int i = 0;
            while (i < input.length() && input.charAt(i) != ']') {
                i++;
            }
            return i;
        }
    
        private String processJsonArray(String input, int count) {
            if (input.charAt(0) == '{') {
                return format(input, count);
            }
    
            StringBuilder sb = new StringBuilder();
            sb.append("[");
            String[] arr = input.substring(1, input.length() - 1).split(",");
            for (String str : arr) {
                sb.append('\n');
                insertTab(sb, count);
                sb.append(str + ',');
            }
            sb.setLength(sb.length() - 1); // omitting the last comma
            sb.append('\n');
            insertTab(sb, count - 1);
            sb.append(']');
            return sb.toString();
        }
    
        private int getEndIndex(String input) {
            int i = 0;
            int count = 0;
            while (i < input.length()) {
                if (input.charAt(i) == '{') {
                    count++;
                } else if (input.charAt(i) == '}') {
                    count--;
                }
                if (count == 0) {
                    return i;
                }
                i++;
            }
            return Integer.MAX_VALUE;
        }
    
    }
    

  • 0
    X

    if module is allowed

    json.dumps(data,sort_keys=True,indent=4)


Log in to reply
 

Looks like your connection to LeetCode Discuss was lost, please wait while we try to reconnect.