Массив JSON в древовидную структуру JSON Массива - PullRequest
0 голосов
/ 20 января 2019

Я хочу написать функцию, которая может принимать массив JSON в древовидную структуру JSON массива.

У меня есть массив JSON, подобный этому:

    var rawData = [{
    "dimension": ["a", "c", "f"],
    "metric": [26]
}, {
    "dimension": ["a", "b", "e"],
    "metric": [12]
}, {
    "dimension": ["a", "d", "e"],
    "metric": [7]
}, {
    "dimension": ["a", "b", "f"],
    "metric": [5]
}, {
    "dimension": ["a", "c", "e"],
    "metric": [2]
}, {
    "dimension": ["a", "d", "f"],
    "metric": [1]
}, {
    "dimension": ["a", "k", ""],
    "metric": [2]
},{
    "dimension": ["b", "c", "d"],
    "metric": [2]
}];

Я ожидаю вывод, как это:

output:
{
    name: 'start',
    children: [{
            name: 'a',
            children: [{
                    name: 'c',
                    children: [{
                        name: 'f',
                        value: 26
                    }, {
                        name: 'e',
                        value: 2
                    }]
                },
                {
                    name: 'b',
                    children: [{
                        name: 'e',
                        value: 12
                    }, {
                        name: 'f',
                        value: 5
                    }]
                },
                {
                    name: 'd',
                    children: [{
                        name: 'e',
                        value: 7
                    }, {
                        name: 'f',
                        value: 1
                    }]
                },
                {
                    name: 'k',
                    value: 2
                }
            ]
        },
        {
            name: 'b',
            children: [{
                name: 'c',
                children: [{
                    name: 'd',
                    value: 2
                }]
            }]
        }
    ]
}

Пожалуйста, помогите мне с небольшим запросом. Я не думаю, что нам нужно больше подробностей относительно этого. Если вы хотите что-то другое, не стесняйтесь комментировать этот пост.

Edit: Чтобы сделать вопрос более простым для понимания.

Редактировать мой код

var output = {
    name: "start",
    children: []
};
var len = rawData.length;
for (var i = 0; i < len; i++) {
    rawChild = rawData[i];
    cat = createJson({}, rawChild.dimension.filter(n => n), rawChild.metric[0]);
    if (i == 0)
        output.children.push(cat);
    else {
        mergeData(output, output.children, cat);
    }
}


function mergeData(parent, child, cat) {
    if (child) {
        for (var index = 0; index < child.length; index++) {
            var element = child[index];

            if (cat.children) {
                if (element.name == cat.name) {
                    parent = mergeData(element, element.children, cat.children[0]);
                    return parent;
                } else {
                    continue;
                }
            } else {
                if (element.name == cat.name) {
                    parent = mergeData(element, element.children, cat);
                    return parent;
                } else {
                    continue;
                }
            }

        }
        parent.children.push(cat);
        return parent;
    } else {
        return;
    }
}
console.log(util.inspect(output, false, null, true));

function createJson(mainObj, names, value) {
    if (!Array.isArray(names)) {
        mainObj.name = names;
        mainObj.value = value;
        return mainObj;
    } else {
        for (var index = 0; index < names.length; index++) {
            if (index == names.length - 1) {
                mainObj = createJson(mainObj, names[index], value);
            } else {
                mainObj.name = names[index];
                newarr = names;
                newarr.shift();
                mainObj.children = [createJson({}, newarr, value)];
            }
        }
    }
    return mainObj;
}

1 Ответ

0 голосов
/ 20 января 2019

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

Во внутреннем lopp выполняется поиск для дочерних элементов с тем же именем, и, если он не найден, создается и вставляется новый набор данных.

Использование внешней проверки для childrrem помогает для более коротких путей, чтоне имеет дочерних свойств.

var rawData = [{ dimension: ["a", "c", "f"], metric: [26] }, { dimension: ["a", "b", "e"], metric: [12] }, { dimension: ["a", "d", "e"], metric: [7] }, { dimension: ["a", "b", "f"], metric: [5] }, { dimension: ["a", "c", "e"], metric: [2] }, { dimension: ["a", "d", "f"], metric: [1] }, { dimension: ["a", "k", ""], metric: [2] }, { dimension: ["b", "c", "d"], metric: [2] }],
    result = { name: "start", children: [] };

rawData.forEach(({ dimension: path, metric: [value] }) => {
    while (!path[path.length - 1]) path.pop(); // remove falsy values from end
    var name = path.pop();
    path
        .reduce((result, name) => {
            var temp = result.find(o => o.name === name);
            if (!temp) {
                result.push(temp = { name });
            }
            temp.children = temp.children || [];
            return temp.children;
        }, result.children)
        .push({ name, value });
});

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