Попытка написать служебную функцию, которая нормализует некоторые глубоко вложенные JSON. Мне удалось создать logi c, который анализирует верхние уровни, но у меня проблемы с его рекурсивной работой. Ниже приведен пример данных.
const editorialSpace = {
sys: {
type: "Array"
},
total: 1,
skip: 0,
limit: 100,
items: [
{
sys: {
space: {
sys: {
type: "Link",
linkType: "Space",
id: "2kqx4czmzra1"
}
},
id: "5nGEaUoREiCP2zqZTD8euc",
type: "Entry",
createdAt: "2020-06-29T16:44:29.447Z",
updatedAt: "2020-06-29T16:44:29.447Z",
environment: {
sys: {
id: "master",
type: "Link",
linkType: "Environment"
}
},
revision: 1,
contentType: {
sys: {
type: "Link",
linkType: "ContentType",
id: "contentSlot"
}
},
locale: "en-US"
},
fields: {
name: "Editorial",
type: "Editorial Index",
metaContentAsset: {
sys: {
type: "Link",
linkType: "Entry",
id: "2YgmIPulwrEHha2QMCD7Xr"
}
},
simpleTextContentAssets: [
{
sys: {
type: "Link",
linkType: "Entry",
id: "4sdFVqXhJk20OY3j9WMdyU"
}
}
],
contentSlots: [
{
sys: {
type: "Link",
linkType: "Entry",
id: "4T5NGaHKAOtGUKoxj4Z9x0"
}
},
{
sys: {
type: "Link",
linkType: "Entry",
id: "2FKoPcIXHNXdbCwDbc83WI"
}
}
]
}
}
],
includes: {
Entry: [
{
sys: {
space: {
sys: {
type: "Link",
linkType: "Space",
id: "2kqx4czmzra1"
}
},
id: "1osX6gbbfA30FMrt4urYw6",
type: "Entry",
createdAt: "2020-06-29T16:44:29.735Z",
updatedAt: "2020-06-30T19:31:30.828Z",
environment: {
sys: {
id: "master",
type: "Link",
linkType: "Environment"
}
},
revision: 2,
contentType: {
sys: {
type: "Link",
linkType: "ContentType",
id: "simpleTextContentAsset"
}
},
locale: "en-US"
},
fields: {
name: "Cool Coats Header",
desktopText: "Here Are Some Very Cool Coats for Fall"
}
},
{
sys: {
space: {
sys: {
type: "Link",
linkType: "Space",
id: "2kqx4czmzra1"
}
},
id: "2FKoPcIXHNXdbCwDbc83WI",
type: "Entry",
createdAt: "2020-06-29T16:44:29.436Z",
updatedAt: "2020-06-29T16:44:29.436Z",
environment: {
sys: {
id: "master",
type: "Link",
linkType: "Environment"
}
},
revision: 1,
contentType: {
sys: {
type: "Link",
linkType: "ContentType",
id: "contentSlot"
}
},
locale: "en-US"
},
fields: {
name: "Fall Travel",
type: "Editorial Story",
metaContentAsset: {
sys: {
type: "Link",
linkType: "Entry",
id: "35SVOUtKoIVdsqR7UcBBbY"
}
},
simpleTextContentAssets: [
{
sys: {
type: "Link",
linkType: "Entry",
id: "3isf647XwHipHE7J3Uxp2E"
}
}
]
}
},
{
sys: {
space: {
sys: {
type: "Link",
linkType: "Space",
id: "2kqx4czmzra1"
}
},
id: "2YgmIPulwrEHha2QMCD7Xr",
type: "Entry",
createdAt: "2020-06-29T16:44:29.522Z",
updatedAt: "2020-06-29T16:44:29.522Z",
environment: {
sys: {
id: "master",
type: "Link",
linkType: "Environment"
}
},
revision: 1,
contentType: {
sys: {
type: "Link",
linkType: "ContentType",
id: "metaContentAsset"
}
},
locale: "en-US"
},
fields: {
title: "Editorial",
description: "This is a selection of editorial content",
identifier: "/editorial"
}
},
{
sys: {
space: {
sys: {
type: "Link",
linkType: "Space",
id: "2kqx4czmzra1"
}
},
id: "2kzZZ8NjUUVVZqse14sJE9",
type: "Entry",
createdAt: "2020-06-29T16:44:29.838Z",
updatedAt: "2020-06-29T16:44:29.838Z",
environment: {
sys: {
id: "master",
type: "Link",
linkType: "Environment"
}
},
revision: 1,
contentType: {
sys: {
type: "Link",
linkType: "ContentType",
id: "metaContentAsset"
}
},
locale: "en-US"
},
fields: {
title: "Cool Coats",
description: "Cool weather coats by top designers",
identifier: "/editorials/coolcoats"
}
},
{
sys: {
space: {
sys: {
type: "Link",
linkType: "Space",
id: "2kqx4czmzra1"
}
},
id: "35SVOUtKoIVdsqR7UcBBbY",
type: "Entry",
createdAt: "2020-06-29T16:44:29.708Z",
updatedAt: "2020-06-29T16:44:29.708Z",
environment: {
sys: {
id: "master",
type: "Link",
linkType: "Environment"
}
},
revision: 1,
contentType: {
sys: {
type: "Link",
linkType: "ContentType",
id: "metaContentAsset"
}
},
locale: "en-US"
},
fields: {
title: "Fall Travel",
description: "Great destinations for fall",
identifier: "/editorial/fall-travel"
}
},
{
sys: {
space: {
sys: {
type: "Link",
linkType: "Space",
id: "2kqx4czmzra1"
}
},
id: "3isf647XwHipHE7J3Uxp2E",
type: "Entry",
createdAt: "2020-06-29T16:44:29.422Z",
updatedAt: "2020-06-29T16:44:29.422Z",
environment: {
sys: {
id: "master",
type: "Link",
linkType: "Environment"
}
},
revision: 1,
contentType: {
sys: {
type: "Link",
linkType: "ContentType",
id: "simpleTextContentAsset"
}
},
locale: "en-US"
},
fields: {
name: "Fall Travel Heading",
desktopText: "Great Fall Travel Ideas"
}
},
{
sys: {
space: {
sys: {
type: "Link",
linkType: "Space",
id: "2kqx4czmzra1"
}
},
id: "4T5NGaHKAOtGUKoxj4Z9x0",
type: "Entry",
createdAt: "2020-06-29T16:44:29.511Z",
updatedAt: "2020-06-29T16:44:29.511Z",
environment: {
sys: {
id: "master",
type: "Link",
linkType: "Environment"
}
},
revision: 1,
contentType: {
sys: {
type: "Link",
linkType: "ContentType",
id: "contentSlot"
}
},
locale: "en-US"
},
fields: {
name: "Cool Coats",
type: "Editorial Story",
metaContentAsset: {
sys: {
type: "Link",
linkType: "Entry",
id: "2kzZZ8NjUUVVZqse14sJE9"
}
},
simpleTextContentAssets: [
{
sys: {
type: "Link",
linkType: "Entry",
id: "1osX6gbbfA30FMrt4urYw6"
}
}
]
}
},
{
sys: {
space: {
sys: {
type: "Link",
linkType: "Space",
id: "2kqx4czmzra1"
}
},
id: "4sdFVqXhJk20OY3j9WMdyU",
type: "Entry",
createdAt: "2020-06-29T16:44:29.419Z",
updatedAt: "2020-06-29T16:44:29.419Z",
environment: {
sys: {
id: "master",
type: "Link",
linkType: "Environment"
}
},
revision: 1,
contentType: {
sys: {
type: "Link",
linkType: "ContentType",
id: "simpleTextContentAsset"
}
},
locale: "en-US"
},
fields: {
name: "Editorial Header",
desktopText: "Here's some great content"
}
}
]
}
};
Вот код, который я написал до сих пор ...
const itemize = fields => {
for (var key in fields) {
if (fields.hasOwnProperty(key)) {
if (typeof fields[key] === "object") {
if (key === "metaContentAsset") {
fields[key] = { id: fields[key].sys.id, fields: {} };
} else {
const entryIds = fields[key].map(element => element.sys.id);
fields[key] = [];
entryIds.forEach(id => fields[key].push({ id: id, fields: {} }));
}
}
}
}
};
const normalizer = (fields, entries) => {
for (var key in fields) {
if (typeof fields[key] === "object" && key !== "contentSlots") {
if (key === "metaContentAsset") {
const matchedEntry = entries.find(entry => {
return entry.sys.id === fields[key].id;
});
fields[key].contentType = matchedEntry.sys.contentType.sys.id;
fields[key].fields = matchedEntry.fields;
} else {
fields[key].map(element => {
const matchedEntry = entries.find(entry => {
return entry.sys.id === element.id;
});
element.contentType = matchedEntry.sys.contentType.sys.id;
element.fields = matchedEntry.fields;
});
}
}
}
};
const mapSlots = (slots, entries) => {
slots.map(slot => {
const matchedEntry = entries.find(entry => {
return entry.sys.id === slot.id;
});
slot.contentType = matchedEntry.sys.contentType.sys.id;
slot.fields = matchedEntry.fields;
});
};
const normalizeJSON = rawObject => {
const normalObject = {};
const items = rawObject.items[0];
normalObject.id = items.sys.id;
normalObject.contentType = items.sys.contentType.sys.id;
normalObject.fields = items.fields;
const fields = normalObject.fields;
//unpacking of items section from raw json
itemize(fields);
//matching nested slots to entries
const slots = normalObject.fields.contentSlots;
const entries = rawObject.includes.Entry;
mapSlots(slots, entries);
//normalize top level fields
normalizer(fields, entries);
return normalObject;
};
normalizeJSON(mockData.editorialSpace);
Любая помощь или направление будут очень благодарны. Я знаю, что мне нужно создать вспомогательную функцию для вызова внутри себя, но не знаю, как и где это сделать. Или, если это возможно, на основе того, что я уже построил. Окончательная форма данных должна напоминать эту.
{
id: '5nGEaUoREiCP2zqZTD8euc',
contentType: 'contentSlot',
fields: {
name: 'Editorial',
type: 'Editorial Index',
metaContentAsset: {
id: '2YgmIPulwrEHha2QMCD7Xr',
fields: [Object],
contentType: 'metaContentAsset'
},
simpleTextContentAssets: [ [Object] ],
contentSlots: [ [Object], [Object] ]
}
}
Где каждый слот содержимого имеет свойство fields, которое будет содержать дополнительные вложенные слоты. Здесь необходимо применить рекурсию.
Спасибо.