简体   繁体   中英

creating nested object from keys

I need to create a object from a json structure. I am confused on how to do the recursive of the structure.

This is my sample json structure

{
        "dynamic.title": "Lorem Ipsum title",
        "dynamic.main_section.header.title": "Lorem Ipsum main section header title ",
        "dynamic.main_section.body.collection.first.title": "Lorem Ipsum main section  body collection first title",
        "dynamic.main_section.body.collection.first.description": "Lorem Ipsum main section  body collection first description",
        "dynamic.main_section.body.collection.first.id": "Lorem Ipsum main section  body collection first id",
        "dynamic.main_section.body.collection.first.child.first.title": "Lorem Ipsum main section  body collection first of first child title ",
        "dynamic.main_section.body.collection.first.child.first.id": "Lorem Ipsum main section  body collection first of first child id ",
        "dynamic.main_section.body.collection.first.child.first.url": "https://loremipsum/1",
        "dynamic.main_section.body.collection.first.child.first.names.first": "John Doe",
        "dynamic.main_section.body.collection.first.child.first.names.second": "Jane Doe",
        "dynamic.main_section.body.collection.second.title": "Lorem Ipsum main section  body collection second title",
        "dynamic.main_section.body.collection.second.description": "Lorem Ipsum main section  body collection second description",
        "dynamic.main_section.body.collection.second.id": "Lorem Ipsum main section  body collection second id",
        "dynamic.main_section.body.collection.second.child.first.title": "Lorem Ipsum main section  body collection second of first child title ",
        "dynamic.main_section.body.collection.second.child.first.id": "Lorem Ipsum main section  body collection second of first child id ",
        "dynamic.main_section.body.collection.second.child.first.url": "https://loremipsum/2",
        "dynamic.main_section.body.collection.second.child.second.title": "Lorem Ipsum main section  body collection second of second child title ",
        "dynamic.main_section.body.collection.second.child.second.id": "Lorem Ipsum main section  body collection second of second child id ",
        "dynamic.main_section.body.collection.second.child.second.url": "https://loremipsum/3"
    }

What i required format is something like this

{
        "dynamic": {
            "title": "Lorem Ipsum title",
            "main_section": {
                "header": {
                    "title": "Lorem Ipsum main section header title "
                },
                "body": {
                    "collection": [
                        {
                            "title": "Lorem Ipsum main section  body collection first title",
                            "description": "Lorem Ipsum main section  body collection first description",
                            "id": "Lorem Ipsum main section  body collection first id",
                            "child": [
                                {
                                    "title": "Lorem Ipsum main section  body collection first of first child title ",
                                    "id": "Lorem Ipsum main section  body collection first of first child id ",
                                    "url": "https://loremipsum/1",
                                    "names": ["John Doe", "Jane Doe"]
                                }
                            ]
                        },
                        {
                            "title": "Lorem Ipsum main section  body collection second title",
                            "description": "Lorem Ipsum main section  body collection second description",
                            "id": "Lorem Ipsum main section  body collection second id",
                            "child": [
                                {
                                    "title": "Lorem Ipsum main section  body collection second of first child title ",
                                    "id": "Lorem Ipsum main section  body collection second of first child id ",
                                    "url": "https://loremipsum/2"
                                },
                                {
                                    "title": "Lorem Ipsum main section  body collection second of second child title ",
                                    "id": "Lorem Ipsum main section  body collection second of second child id ",
                                    "url": "https://loremipsum/3"
                                }
                            ]
                        }
                    ]
                }
            }
        }
    }

If the left side key consist of first second then it will be an array, but if more than one property exist then it will be an object or else it could be an array.

How could i achieve this in js?

You need to replace numerals to indices and check the keys for having objects or arrays.

 const setValue = (object, path, value) => { const indices = { first: 0, second: 1 }, keys = path.replace(new RegExp(Object.keys(indices).join('|'), 'g'), k => indices[k]).split('.'), last = keys.pop(); keys.reduce((o, k, i, kk) => o[k]??= isFinite(i + 1 in kk? kk[i + 1]: last)? []: {}, object) [last] = value; return object; }, data = { "dynamic.title": "Lorem Ipsum title", "dynamic.main_section.header.title": "Lorem Ipsum main section header title ", "dynamic.main_section.body.collection.first.title": "Lorem Ipsum main section body collection first title", "dynamic.main_section.body.collection.first.description": "Lorem Ipsum main section body collection first description", "dynamic.main_section.body.collection.first.id": "Lorem Ipsum main section body collection first id", "dynamic.main_section.body.collection.first.child.first.title": "Lorem Ipsum main section body collection first of first child title ", "dynamic.main_section.body.collection.first.child.first.id": "Lorem Ipsum main section body collection first of first child id ", "dynamic.main_section.body.collection.first.child.first.url": "https://loremipsum/1", "dynamic.main_section.body.collection.first.child.first.names.first": "John Doe", "dynamic.main_section.body.collection.first.child.first.names.second": "Jane Doe", "dynamic.main_section.body.collection.second.title": "Lorem Ipsum main section body collection second title", "dynamic.main_section.body.collection.second.description": "Lorem Ipsum main section body collection second description", "dynamic.main_section.body.collection.second.id": "Lorem Ipsum main section body collection second id", "dynamic.main_section.body.collection.second.child.first.title": "Lorem Ipsum main section body collection second of first child title ", "dynamic.main_section.body.collection.second.child.first.id": "Lorem Ipsum main section body collection second of first child id ", "dynamic.main_section.body.collection.second.child.first.url": "https://loremipsum/2", "dynamic.main_section.body.collection.second.child.second.title": "Lorem Ipsum main section body collection second of second child title ", "dynamic.main_section.body.collection.second.child.second.id": "Lorem Ipsum main section body collection second of second child id ", "dynamic.main_section.body.collection.second.child.second.url": "https://loremipsum/3" }, result = Object.entries(data).reduce((r, [k, v]) => setValue(r, k, v), {}); console.log(result);
 .as-console-wrapper { max-height: 100%;important: top; 0; }

I show you the way to transform the data so that you continue with it and even automate it if necessary;

 let data = { "dynamic.title": "Lorem Ipsum title", "dynamic.main_section.header.title": "Lorem Ipsum main section header title ", "dynamic.main_section.body.collection.first.title": "Lorem Ipsum main section body collection first title" } dataTrans = {} //data["dynamic.title"] dataTrans.dynamic = {} dataTrans.dynamic.title = data["dynamic.title"] //data["dynamic.main_section.header.title"] dataTrans.dynamic.main_section = {} dataTrans.dynamic.main_section.header = {} dataTrans.dynamic.main_section.header.title = data["dynamic.main_section.header.title"] dataTrans.dynamic.main_section.body = {} dataTrans.dynamic.main_section.body.collection = [] dataTrans.dynamic.main_section.body.collection[0] = {} dataTrans.dynamic.main_section.body.collection[0].title = data["dynamic.main_section.body.collection.first.title"] console.log(dataTrans)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM