Лучший способ отобразить глубокий объект на новый объект - PullRequest
1 голос
/ 11 апреля 2019

Этот код работает для преобразования JSON в объект, где каждый объект имени превращается в ключ либо для своего значения, либо, если у него вместо этого есть свой собственный объектный элемент, это прерывается и делает то же самое с его содержимым.

Есть ли лучший способ сделать это, который также позволил бы увеличить гибкость схемы JSON?
Есть ли способ, которым я могу получить все это до более простой функции, которую я могу передать первому элементу и преобразовать егодо какой глубины идет схема?

const fs = require('fs');
{
    let scheme = JSON.parse('{"$schema":{"root":{"name":"THINGY","dtd":{"name":"DOCTYPE","value":"something.dtd","commentBefore":["?xml version='1.0'?","Version NULL"]},"ele":{"name":"REPORT","ele":[{"name":"SEGMENT0","ele":[{"name":"NUMBER1","value":""},{"name":"NUMBER2","value":""}]},{"name":"SEGMENT1","ele":[{"name":"RECORD1","ele":[{"name":"NUMBER1","value":""},{"name":"NUMBER2","value":""}]}]},{"name":"SEGMENT2","ele":[]},{"name":"SEGMENT3","ele":[]},{"name":"SEGMENT4","ele":[]},{"name":"SEGMENT5","ele":[]}]}}}}').$schema.root;
    let depth = 0;

    var compiled = {
        [scheme.ele.name]: scheme.ele.ele.map(function(i) {
            if (typeof i.ele != 'undefined') {
                return {
                    [i.name]: i.ele.map(function(k) {
                        if (typeof k.ele != 'undefined') {
                            return {
                                [k.name]: k.ele.map(function(p) {
                                    if (typeof p.ele != 'undefined') {
                                        return {
                                            [p.name]: p.ele
                                        };
                                    } else {
                                        return {
                                            [p.name]: p.value
                                        };
                                    }
                                })
                            };
                        } else {
                            return {
                                [k.name]: k.value
                            };
                        }
                    })
                };
            } else {
                return {
                    [i.name]: i.value
                };
            }
        })
    };
}

console.log(JSON.stringify(compiled, 0, 2));

Я должен добавить, что это в конечном итоге также предназначено для применения валидации и получения реальных данных при получении к строковым объектам.

Выводвыглядит так:

{
    "REPORT": [
    {
        "SEGMENT0": [
        {
            "NUMBER1": ""
        },
        {
            "NUMBER2": ""
        }
        ]
    },
    {
        "SEGMENT1": [
        {
            "RECORD1": [
            {
                "NUMBER1": ""
            },
            {
                "NUMBER2": ""
            }
            ]
        }
        ]
    },
    {
        "SEGMENT2": []
    },
    {
        "SEGMENT3": []
    },
    {
        "SEGMENT4": []
    },
    {
        "SEGMENT5": []
    }
    ]
}

Ответы [ 2 ]

5 голосов
/ 11 апреля 2019

Вы можете деструктурировать объект, получить name, ele и value и вернуть новый объект с ключом name и массивом, сопоставив объекты ele или value.

const
    getData = ({ name, ele, value }) => ({
        [name]: Array.isArray(ele)
            ? ele.map(getData)
            : value
    });

var scheme = JSON.parse('{"$schema":{"root":{"name":"THINGY","dtd":{"name":"DOCTYPE","value":"something.dtd","commentBefore":["?xml version=\'1.0\'?","Version NULL"]},"ele":{"name":"REPORT","ele":[{"name":"SEGMENT0","ele":[{"name":"NUMBER1","value":""},{"name":"NUMBER2","value":""}]},{"name":"SEGMENT1","ele":[{"name":"RECORD1","ele":[{"name":"NUMBER1","value":""},{"name":"NUMBER2","value":""}]}]},{"name":"SEGMENT2","ele":[]},{"name":"SEGMENT3","ele":[]},{"name":"SEGMENT4","ele":[]},{"name":"SEGMENT5","ele":[]}]}}}}').$schema.root,
    result = getData(scheme.ele);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
1 голос
/ 11 апреля 2019

Ответ Нины чище, но это немного похоже на ваш код, поэтому я решил, что все равно его опубликую.

let scheme = JSON.parse('{"$schema":{"root":{"name":"THINGY","dtd":{"name":"DOCTYPE","value":"something.dtd","commentBefore":["?xml version=\'1.0 \'?","Version NULL"]},"ele":{"name":"REPORT","ele":[{"name":"SEGMENT0","ele":[{"name":"NUMBER1","value":""},{"name":"NUMBER2","value":"1"}]},{"name":"SEGMENT1","ele":[{"name":"RECORD1","ele":[{"name":"NUMBER1","value":"2"},{"name":"NUMBER2","value":""}]}]},{"name":"SEGMENT2","ele":[]},{"name":"SEGMENT3","ele":[]},{"name":"SEGMENT4","ele":[]},{"name":"SEGMENT5","ele":[]}]}}}}').$schema.root;
let newScheme = JSON.parse('{"$schema":{"root":{"name":"THINGY","dtd":{"name":"DOCTYPE","value":"something.dtd","commentBefore":["?xml version=\'1.0 \'?","Version NULL"]},"ele":{"name":"REPORT","ele":[{"name":"SEGMENT0","ele":[{"name":"NUMBER1","value":"1"},{"name":"NUMBER2","value":"3"}]},{"name":"SEGMENT1","ele":[{"name":"RECORD1","ele":[{"name":"NUMBER1","value":"4"},{"name":"NUMBER2","value":""}]}]},{"name":"SEGMENT2","ele":[]},{"name":"SEGMENT3","ele":[]},{"name":"SEGMENT4","ele":[]},{"name":"SEGMENT5","ele":[]}]}}}}').$schema.root;

//Yay, recursion!
function mapObj(a, o = {}) {

  let array = o[a.name] || [];

  for (let i = 0; i < a.ele.length; i++) {

    let b = a.ele[i];
    array[i] = b.ele ?
      mapObj(b, array[i]) : {
        [b.name]: b.value
      };
  }
  
  o[a.name] = array;
  return o;

}

let obj = mapObj(scheme.ele);

console.log(obj);
console.log(mapObj(newScheme.ele, obj));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...