Обработка объектов для создания нового объекта

50
7

Я пытаюсь создать новую структуру объекта из существующего объекта.

В настоящее время набор данных выглядит следующим образом:

const jsonStructure = {
"a11/a22/animations": "snimations",
"a11/a22/colours": "sl/colours",
"a11/a22/fonts": "sbal/fonts",
"a11/a22/visibility": "sisibility",
"a11/b22/logo": "sages/logo",
"a11/c22/define": "sst/define",
"a11/c22/ordered": "st/ordered",
"a11/c22/unordered": "sunordered",
"a11/d22/foot": "smeta/foot",
"a11/d22/head": "smeta/head",
"a11/e22/blockquote": "slockquote",
"a11/e22/headings": "s/headings",
"a11/e22/hr": "ss/e/hr",
"a11/e22/inline-elements": "s-elements",
"a11/e22/paragraph": "sparagraph",
"a11/e22/preformatted": "sformatted",
"a11/e22/time": "stext/time",
"b11/f22/menu": "smenu/menu",
"b11/g22/product-item": "sduct-item",
"b11/h22/search": "sch/search",
"b11/i22/sub-menu": "s/sub-menu",
"c11/j22/footer": "ser/footer",
"c11/j22/title": "ster/title",
"c11/k22/header": "ser/header"
};

То, что я хочу достичь, - это структура данных:

{
"a11": {
"a22": {
"animations": {
"value": "snimations"
},
"colours": {
"value": "sl/colours"
}
},
"b22": {
"logo":{
"value": "sbal/fonts"
}
}
"c22": {
"define":{
"value": "sst/define"
},
"ordered":{
"value": "st/ordered"
}
}
},
"b11": {
"f22": {
"menu": {
"value": "smenu/menu"
}
},
}
}

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

const structure = {
a: {},
b: {},
c: {}
};

let a11 = [];
let b11 = [];
let c11 = [];

for (var hbp in jsonStructure) {
if (hbp.includes("a11")) {

}
if (hbp.includes("b11")) {

}
if (hbp.includes("c11")) {

}
}

спросил(а) 2018-08-28T23:14:00+03:00 1 год, 5 месяцев назад
1
Решение
61

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

var input = { "a11/a22/animations": "snimations", "a11/a22/colours": "sl/colours", "a11/a22/fonts": "sbal/fonts", "a11/a22/visibility": "sisibility", "a11/b22/logo": "sages/logo", "a11/c22/define": "sst/define", "a11/c22/ordered": "st/ordered", "a11/c22/unordered": "sunordered", "a11/d22/foot": "smeta/foot", "a11/d22/head": "smeta/head", "a11/e22/blockquote": "slockquote", "a11/e22/headings": "s/headings", "a11/e22/hr": "ss/e/hr", "a11/e22/inline-elements": "s-elements", "a11/e22/paragraph": "sparagraph", "a11/e22/preformatted": "sformatted", "a11/e22/time": "stext/time", "b11/f22/menu": "smenu/menu", "b11/g22/product-item": "sduct-item", "b11/h22/search": "sch/search", "b11/i22/sub-menu": "s/sub-menu", "c11/j22/footer": "ser/footer", "c11/j22/title": "ster/title", "c11/k22/header": "ser/header" },
output = {};

Object
.entries(input)
.forEach(([k, v]) =>
k.split('/').reduce((o, k) => o[k] = o[k] || {}, output).value = v);

console.log(output);

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

ответил(а) 2018-08-28T23:20:00+03:00 1 год, 5 месяцев назад
49

Вы можете использовать .split чтобы получить все пути и создать вложенный объект:


 const result = {};

for(const [key, value] of Object.entries(jsonStructure)) {
let acc = result;
for(const path of key.split("/"))
acc = (acc[path] || (acc[path] = {}));
acc.value = value;
}

ответил(а) 2018-08-28T23:20:00+03:00 1 год, 5 месяцев назад
35

Другие ответы здесь замечательные и дают вам решения без необходимости использования внешнего пакета. Однако, возможно, стоит обратить внимание на плоский пакет на npm, который можно использовать для развязывания объекта. Вам нужно будет установить разделитель на "/" в вашем случае так:

var unflatten = require('flat').unflatten

unflatten(yourObject, { delimiter: '/' })

ответил(а) 2018-08-29T00:54:00+03:00 1 год, 5 месяцев назад
36

Итерации над entries входного объекта с использованием вложенного reduce для идентификации (и создания, если необходимо) вложенного объекта в накопителе и последующего присвоения его value свойства:

const jsonStructure={"a11/a22/animations":"snimations","a11/a22/colours":"sl/colours","a11/a22/fonts":"sbal/fonts","a11/a22/visibility":"sisibility","a11/b22/logo":"sages/logo","a11/c22/define":"sst/define","a11/c22/ordered":"st/ordered","a11/c22/unordered":"sunordered","a11/d22/foot":"smeta/foot","a11/d22/head":"smeta/head","a11/e22/blockquote":"slockquote","a11/e22/headings":"s/headings","a11/e22/hr":"ss/e/hr","a11/e22/inline-elements":"s-elements","a11/e22/paragraph":"sparagraph","a11/e22/preformatted":"sformatted","a11/e22/time":"stext/time","b11/f22/menu":"smenu/menu","b11/g22/product-item":"sduct-item","b11/h22/search":"sch/search","b11/i22/sub-menu":"s/sub-menu","c11/j22/footer":"ser/footer","c11/j22/title":"ster/title","c11/k22/header":"ser/header"}

const output = Object.entries(jsonStructure).reduce((a, [keysStr, val]) => {
const keys = keysStr.split('/');
const finalObj = keys.reduce((nestedObj, key) => {
if (!nestedObj[key]) nestedObj[key] = {};
return nestedObj[key];
}, a);
finalObj.value = val;
return a;
}, {});
console.log(output);

ответил(а) 2018-08-28T23:19:00+03:00 1 год, 5 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема