3

I have an array of conversation between two entities, each distinguished based on parent and level. Every request will be followed by a response object. The sample input structure is like below

[
{ "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 }
]

I am trying to generate a json based on request and its corresponding response. Below is the method which I am using to achieve it

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));

The response which I am getting is not structured based on the request entity. Response from the above method

[
{
    "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":
        {}
    }
}]

The Response objects are getting seperated. The expected json output is like below

{
    "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"
                                }
                            }
                        ]
                    }
                }
            ]
        }
    }]
}

Please suggest where I am going wrong. Anything to change in the input structure to get the desired output.

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

2 Answers 2

3

If the 'response' type is always directly coming after 'request', then you could build a new object with a look ahead to the next object and insert this message into the new object as result.

This proposal uses an array for the level reference and updates the levels in that array and as well as in the result.

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; }

Sign up to request clarification or add additional context in comments.

Comments

1

I tried to do it using lodash in a very complex way as below .

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;

        }


    }
}

Not sure if it work for all scenerios . @Nina Scholz great answer.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.