在javascript

时间:2018-03-12 10:14:32

标签: javascript json parsing hierarchical-data

我在两个实体之间有一系列对话,每个实体根据父级和级别进行区分。每个请求后面都会有一个响应对象。样本输入结构如下所示

[
{ "message": "one", "messageSequence": 0, "level": 1, "Parent": "", "messageType": "request" },
{ "message": "two", "messageType": "response", "messageSequence": 1 },
{ "message": "three-1 (3.1)", "messageSequence": 2, "level": 2, "Parent": 1, "messageType": "request" },
{ "message": "four", "messageType": "response", "messageSequence": 3 },
{ "message": "five-1 (5.1)", "messageSequence": 4, "level": 3, "Parent": 2, "messageType": "request" },
{ "message": "six", "messageType": "response", "messageSequence": 5 },
{ "message": "five-2 (5.2)", "messageSequence": 6, "level": 3, "Parent": 2, "messageType": "request" },
{ "message": "seven", "messageType": "response", "messageSequence": 7 },
{ "message": "three-2 (3.2)", "messageSequence": 8, "level": 2, "Parent": 1, "messageType": "request" },
{ "message": "eight", "messageType": "response", "messageSequence": 9 },
{ "message": "nine-1 (9.1)", "messageSequence": 10, "level": 3, "Parent": 2, "messageType": "request" },
{ "message": "ten", "messageType": "response", "messageSequence": 11 },
{ "message": "nine-2 (9.2) ", "messageSequence": 12, "level": 3, "Parent": 2, "messageType": "request" },
{ "message": "eleven", "messageType": "response", "messageSequence": 13 }
]

我正在尝试根据请求及其相应的响应生成json。以下是我用来实现它的方法

var prevLevel;
var lastUserItem = 0;
function convertToJson(array) {
    var map = {};
    for (var i = 0; i < array.length; i++) {
        var obj = array[i];
        if (array[i].messageType == "request")
            obj.request = [];
        else
            obj.response = {};

        if (obj.level) {
            prevLevel = obj.level
            map[obj.level] = obj;

            var parent = obj.Parent || '-';
            if (!map[parent]) {
                map[parent] = {
                    request: []
                };
            }
            delete obj.Parent;
            delete obj.level;
            delete obj.messageType;
            delete obj.messageSequence;
            map[parent].request.push(obj);
            lastUserItem = map[parent].request.length - 1;
        } else {
            delete obj.Parent;
            delete obj.level;
            delete obj.messageType;
            delete obj.messageSequence;
            if (map[prevLevel].request && map[prevLevel].request.length > 0) {
                map[prevLevel].request[lastUserItem].response = {};
                map[prevLevel].request[lastUserItem].response = obj;
            } else {

                map[prevLevel].response = {};
                map[prevLevel].response = obj;
            }
        }
    }

    return map['-'].request;

}
var r = convertToJson(messages);
console.log(JSON.stringify(r));

我得到的回复不是基于请求实体构建的。 上述方法的回应

[
{
    "message": "one",
    "request": [
    {
        "message": "three-1 (3.1)",
        "request": [
        {
            "message": "five-1 (5.1)",
            "request": [],
            "response":
            {
                "message": "six",
                "response":
                {}
            }
        },
        {
            "message": "five-2 (5.2)",
            "request": [],
            "response":
            {
                "message": "seven",
                "response":
                {}
            }
        }],
        "response":
        {
            "message": "four",
            "response":
            {}
        }
    },
    {
        "message": "three-2 (3.2)",
        "request": [
        {
            "message": "nine-1 (9.1)",
            "request": [],
            "response":
            {
                "message": "ten",
                "response":
                {}
            }
        },
        {
            "message": "nine-2 (9.2) ",
            "request": [],
            "response":
            {
                "message": "eleven",
                "response":
                {}
            }
        }],
        "response":
        {
            "message": "eight",
            "response":
            {}
        }
    }],
    "response":
    {
        "message": "two",
        "response":
        {}
    }
}]

Response对象正在分离。预期的json输出如下所示

{
    "request": [{
        "message": "one",
        "response": {
            "message": "two"
            "request": [{
                    "message": "three-1 (3.1)",
                    "response": {
                        "message": "four"
                        "request": [{
                                "message": "five-1 (5.1)",
                                "response": {
                                    "message": "six"
                                }
                            },
                            {
                                "message": "five-2 (5.2)",
                                "response": {
                                    "message": "seven"
                                }
                            }
                        ]
                    }
                },
                {
                    "message": "three-2 (3.2)",
                    "response": {
                        "message": "eight",
                        "request": [{
                                "message": "nine-1 (9.1)",
                                "response": {
                                    "message": "ten"
                                }
                            },
                            {
                                "message": "nine-2 (9.2) ",
                                "response": {
                                    "message": "eleven"
                                }
                            }
                        ]
                    }
                }
            ]
        }
    }]
}

请告诉我哪里出错了。在输入结构中要改变的任何东西,以获得所需的输出。

https://jsfiddle.net/49qLhL8g/4/

2 个答案:

答案 0 :(得分:3)

如果'response'类型总是直接在'request'之后,那么您可以构建一个新对象,并向前看下一个对象,并将此消息作为结果插入到新对象中。

此提案使用数组作为关卡参考,并更新该数组和结果中的关卡。

var data = [{ message: "one", messageSequence: 0, level: 1, Parent: "", messageType: "request" }, { message: "two", messageType: "response", messageSequence: 1 }, { message: "three-1 (3.1)", messageSequence: 2, level: 2, Parent: 1, messageType: "request" }, { message: "four", messageType: "response", messageSequence: 3 }, { message: "five-1 (5.1)", messageSequence: 4, level: 3, Parent: 2, messageType: "request" }, { message: "six", messageType: "response", messageSequence: 5 }, { message: "five-2 (5.2)", messageSequence: 6, level: 3, Parent: 2, messageType: "request" }, { message: "seven", messageType: "response", messageSequence: 7 }, { message: "three-2 (3.2)", messageSequence: 8, level: 2, Parent: 1, messageType: "request" }, { message: "eight", messageType: "response", messageSequence: 9 }, { message: "nine-1 (9.1)", messageSequence: 10, level: 3, Parent: 2, messageType: "request" }, { message: "ten", messageType: "response", messageSequence: 11 }, { message: "nine-2 (9.2) ", messageSequence: 12, level: 3, Parent: 2, messageType: "request" }, { message: "eleven", messageType: "response", messageSequence: 13 }],
    result = [],
    levels = [result];

data.forEach(function (o, i, a) {
    var level = o.level - 1, temp;
    if (o.messageType !== 'request') {
        return;
    }
    temp = { message: o.message, response: { message: a[i + 1].message, request: [] } };
    levels[level + 1] = temp.response.request;
    levels[level].push(temp);
});

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 1 :(得分:1)

我尝试使用lodash以非常复杂的方式执行此操作。

var _lodash = require('lodash');

var arrayTwo = [
    { "message": "one", "messageSequence": 0, "level": 1, "Parent": "", "messageType": "request" },
    { "message": "two", "messageType": "response", "messageSequence": 1, "Parent": 0 },
    { "message": "three-1 (3.1)", "messageSequence": 2, "level": 2, "Parent": 1, "messageType": "request" },
    { "message": "four", "messageType": "response", "messageSequence": 3, "Parent": 2 },
    { "message": "five-1 (5.1)", "messageSequence": 4, "level": 3, "Parent": 2, "messageType": "request" },
    { "message": "six", "messageType": "response", "messageSequence": 5, "Parent": 3 },
    { "message": "five-2 (5.2)", "messageSequence": 6, "level": 3, "Parent": 2, "messageType": "request" },
    { "message": "seven", "messageType": "response", "messageSequence": 7, "Parent": 3 },
    { "message": "seven-1 (7.1)", "messageSequence": 8, "level": 4, "Parent": 3, "messageType": "request" },
    { "message": "seven-2 (7.2)", "messageType": "response", "messageSequence": 9, "Parent": 4 },
    { "message": "three-2 (3.2)", "messageSequence": 10, "level": 2, "Parent": 1, "messageType": "request" },
    { "message": "eight", "messageType": "response", "messageSequence": 11, "Parent": 2 },
    { "message": "nine-1 (9.1)", "messageSequence": 12, "level": 3, "Parent": 2, "messageType": "request" },
    { "message": "ten", "messageType": "response", "messageSequence": 13, "Parent": 3 },
    { "message": "nine-2 (9.2) ", "messageSequence": 14, "level": 3, "Parent": 2, "messageType": "request" },
    { "message": "eleven", "messageType": "response", "messageSequence": 15, "Parent": 3 }
];

var finalObj = {};

for (var i = 0; i < arrayTwo.length; i++) {
    if (arrayTwo[i].messageType == "request") {
        findAndAppendToRequest(arrayTwo[i]);
    } else {
        findAndAppendToResponse(arrayTwo[i]);
    }
}
console.log(JSON.stringify(finalObj));

function findAndAppendToResponse(item) {
    var parent = item.Parent;
    var res = findBotNode();
    var dt = _lodash.get(finalObj, res);
    if (dt) {
        if (!_lodash.has(finalObj, res + ".response")) {
            _lodash.set(finalObj, res + ".response", {});
        }
        var data = {};
        data.message = item.message;

        _lodash.set(finalObj, res + ".response", data);
    }

    function findBotNode() {
        var t = "";
        if (parent == 0) {
            t = 'request[' + 0 + ']';
        } else {
            for (var i = 0; i < parent; i++) {
                if (!t) {
                    t = 'request[' + i + ']';
                } else {
                    var temp = t + '.response.request[' + i + ']';
                    var cnt = 1;
                    while (!checkIfExists(temp)) {
                        temp = "";
                        var val = i - cnt;
                        temp = t + '.response.request[' + val + ']';
                        cnt++;
                    }
                    t = temp;
                }
            }

        }
        return t;
    }

}

function checkIfExists(val) {
    return _lodash.get(finalObj, val);
}

function findAndAppendToRequest(item) {
    var msg = {};
    msg.message = item.message;
    if (!finalObj.request) {
        finalObj.request = [];
        finalObj.request.push(msg);
    } else {
        var parent = item.Parent;
        var res = traverseNode();
        var dt = _lodash.get(finalObj, res);
        if (dt) {
            if (!_lodash.has(finalObj, res + ".request")) {
                _lodash.set(finalObj, res + ".request", []);
            }
            var ob = _lodash.get(finalObj, res + ".request");
            ob.push(msg);
            _lodash.set(finalObj, res + ".request", ob);
        }

        function traverseNode() {
            var t = "";
            for (var i = 0; i < parent; i++) {
                if (!t) {
                    t = 'request[' + i + '].response';
                } else {
                    var temp = t + '.request[' + i + '].response';
                    var cnt = 1;
                    while (!checkIfExists(temp)) {
                        temp = "";
                        var val = i - cnt;
                        temp = t + '.request[' + val + '].response';
                        cnt++;
                    }
                    t = temp;
                }
            }
            return t;

        }


    }
}

不确定它是否适用于所有场景。 @Nina Scholz很棒的回答。