如何有效地将json转换为缩进文本树?

时间:2016-08-26 17:51:55

标签: javascript json

给出像这样的JSON:

{
    Normalize: {},
    Typography: {},
    'Flex-grid': {},
    Elements: {},
    Forms: {},
    Navigation: {
        Links: {},
        Menus: {}
    },
    Accessibility: {},
    Alignments: {},
    Clearings: {},
    Widgets: {},
    Content: {
        'Posts-and-pages': {},
        Comments: {}
    },
    'Infinite-scroll': {},
    Media: {
        Captions: {},
        Galleries: {}
    }
}

我想生成一个缩进的纯文本,如下所示:

# Normalize
# Typography
# Flex grid
# Elements
# Forms
# Navigation
    ## Links
    ## Menus
# Accessibility
# Alignments
# Clearings
# Widgets
# Content
    ## Posts and pages
    ## Comments
# Infinite scroll
# Media
    ## Captions
    ## Galleries

我已经想出了一些快速而又脏的代码(我是一个javascript初学者)来实现这一目标。当我运行代码时,它看起来很慢。我该怎么做才能更快更有效?

function jsonToIndentedText(json) {
    var text = JSON.stringify(json, null, '\t');

    var indentedText = [];

    var lines = text.split('\n');

    lines.forEach(function(line) {
        if ('{' == line || '{' == line || '' == line) {
            return;
        }

        var textNow = line.replace(/"/gi, '').replace(/:[\s | \S]*$/i, '');

        if (textNow.search("}") < 0) {
            textNowArr = textNow.split(/\t/gi);
            level = textNowArr.length - 1;
            var indents = '';
            var hashes = '#';
            for (var i = 1; i < level; i++) {
                indents += '\t';
                hashes += '#';
            }
            indentedText.push(indents + hashes + ' ' + textNow.replace(/\t/gi, '').replace(/-/gi,' '));
        }

    });
    return indentedText.join('\n');
}

这是我的傻瓜:https://jsfiddle.net/94t4dyag/1/

2 个答案:

答案 0 :(得分:1)

我认为您不应该将对象转换为JSON字符串,然后使用javascript手动解析字符串 - 尤其是当对象本身代表JSON字符串时。

尝试这样的事情:

function prettify(obj){

    return recurse(0, obj);        

    function recurse(level, obj){
        var result = "";
        foreach(var prop in obj)
        if(obj.hasOwnProperty(prop))
        {
            result += printIndents(level);//TODO write this
            result += prop + "\n"; 
            result += recurse(level + 1, obj[prop]);
        }

        return result;
    }
}

答案 1 :(得分:1)

我建议使用对象本身,因为你不需要字符串操作。

此提议使用一个函数进行递归调用,将对象作为参数和实际深度级别。

函数内部从对象获取所有键并迭代它们。然后检查值是否为对象。使用对象,使用acual对象和增加的级别再次调用该函数。

如果找到值,则将该值添加到结果字符串中。

function print(object, level) {
    var SPACER = '    ',
        NEWLINE = '\n'
        result = '';

    level = level || 0;
    Object.keys(object).forEach(function (key) {
        var i = level;
        while (i--) {
            result += SPACER;
        }
        if (typeof object[key] === 'object' && object[key] !== null) {
            result += key + NEWLINE;
            result += print(object[key], level + 1);
            return;
        }
        result += key + ': ' + object[key] + NEWLINE;

    });
    return result;
}

var data = { Normalize: { somekey: 1 }, Typography: { anotherkey: 2 }, 'Flex-grid': {}, Elements: {}, Forms: {}, Navigation: { Links: {}, Menus: {} }, Accessibility: {}, Alignments: {}, Clearings: {}, Widgets: {}, Content: { 'Posts-and-pages': {}, Comments: {} }, 'Infinite-scroll': {}, Media: { Captions: {}, Galleries: {} } };
document.getElementById('pre').innerHTML = print(data);
<pre id="pre"></pre>