Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting Flat array to json in javascript

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/

like image 783
Raghavendra Avatar asked Sep 22 '26 09:09

Raghavendra


2 Answers

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; }
like image 126
Nina Scholz Avatar answered Sep 24 '26 22:09

Nina Scholz


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.

like image 28
user2703788 Avatar answered Sep 25 '26 00:09

user2703788



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!