Как переструктурировать массив в javaScript?
Заранее прошу прощения за такой объем строк кода! Помогите, пожалуйста, переструктурировать массив. Сейчас мне приходят данные в виде массива таких объектов (условно, кейсов может быть больше):
let dataToExpandToCheck= [
{
codePlatform: 'Platform 1',
codeInstance: 'Instance 1',
codeScheme: 'Scheme 1',
codeTable: 'Table 1",
columns: []
},
{
codePlatform: 'Platform 1',
codeInstance: 'Instance 1',
codeScheme: 'Scheme 1',
codeTable: 'Table 2",
columns: []
},
{
codePlatform: 'Platform 1',
codeInstance: 'Instance 1',
codeScheme: 'Scheme 2',
codeTable: 'Table 1",
columns: []
},
{
codePlatform: 'Platform 1',
codeInstance: 'Instance 2',
codeScheme: 'Scheme 1',
codeTable: 'Table 1",
columns: []
},
{
codePlatform: 'Platform 2',
codeInstance: 'Instance 1',
codeScheme: 'Scheme 1',
codeTable: 'Table 1",
columns: []
},
]
Суть задачи в том, что в рамках одной платформы (codePlatform) может быть несколько инстансов (codeInstance), а внутри одного инстанса несколько разных схем (codeScheme), а внутри схем несколько разных таблиц (codeTable). В тех данных, которые я привела: есть 2 платформы (1 и 2). Внутри платформы 1 существует 2 инстанса (1 и 2), внутри инстанса 1 есть схема 1 и схема 2, в схеме 1 лежит 2 таблицы. На платформе 2 один инстанс, одна схема и одна таблица.
Мне необходимо для отправки данных переписать данный массив так, чтобы объект Платформа содержал ее имя и массив с ее инстансами, объект каждого инстанса должен содержать имя инстанса и массив со всеми входящими в него схемами, а объект каждой схемы содержит ее имя и массив с входящими в нее таблицами (объект таблицы, соответственно, включает в себя имя таблицы и массив ее колонок columns). Таким образом в итоге массив должен выглядеть так (повторюсь, в рабочем проекте данных больше и вариантов гораздо больше):
let restrArray = [
{
codePlatform: 'Platform 1',
instances: [
{
codeInstance: 'Instance 1',
schemes: [
{
codeScheme: 'Scheme1',
tables: [
{
codeTable: 'Table 1',
columns: []
},
{
codeTable: 'Table 2',
columns: []
}
]
},
{
codeScheme: 'Scheme 2',
tables: [
{
codeTable: 'Table 1',
columns: []
}
]
}
]
},
{
codeInstance: 'Instance 2',
schemes: [
{
codeScheme: 'Scheme1',
tables: [
{
codeTable: 'Table 1',
columns: []
}
]
}
]
}
]
},
{
codePlatform: 'Platform 2',
instances: [
{
codeInstance: 'Instance 1',
schemes: [
{
codeScheme: 'Scheme 1',
tables: [
{
codeTable: 'Table 1',
columns: []
}
]
}
]
}
]
}
]
Я прописала алгоритм, но он работает некорректно: в некоторых случаях не добавляет инстанс в объект платформы, иногда дублирует таблицы в массиве. Помогите, пожалуйста, понять, как переписать алгоритм:
const restructureFinalDataToSend = (
dataToExpandToCheck,
setRestructuredDataToSend
) => {
let newDataArray = [];
let instanceArray = [];
let instanceObject = {};
let schemesArray = [];
let schemeObject = {};
let tablesArray = [];
let tableObject = {};
let platformObject = {};
for (let i = 0; i < dataToExpandToCheck.length; i++) {
for (let j = 0; j < i; j++) {
if (
dataToExpandToCheck[j].codePlatform ===
dataToExpandToCheck[i].codePlatform
) {
if (
dataToExpandToCheck[j].codeInstance ===
dataToExpandToCheck[i].codeInstance
) {
if (
dataToExpandToCheck[j].codeScheme ===
dataToExpandToCheck[i].codeScheme
) {
tableObject = {
codeTable: dataToExpandToCheck[i].codeTable,
columns: dataToExpandToCheck[i].columns
};
tablesArray.push(tableObject);
schemeObject = {
codeScheme: dataToExpandToCheck[i].codeScheme,
tables: tablesArray
};
schemesArray.push(schemeObject);
instanceObject = {
codeInstance: dataToExpandToCheck[i].codeInstance,
schemes: schemesArray.reduce((o, i) => {
if (
!o.find((v) => v.codeScheme == i.codeScheme)
) {
o.push(i);
}
return o;
}, [])
};
instanceArray.push(instanceObject);
platformObject = {
codePlatform: dataToExpandToCheck[i].codePlatform,
instances: instanceArray.reduce((o, i) => {
if (
!o.find(
(v) => v.codeInstance == i.codeInstance
)
) {
o.push(i);
}
return o;
}, [])
};
newDataArray.push(platformObject);
} else {
schemeObject = {
codeScheme: dataToExpandToCheck[i].codeScheme,
tables: [
{
codeTable: dataToExpandToCheck[i].codeTable,
columns: dataToExpandToCheck[i].columns
}
]
};
schemesArray.push(schemeObject);
instanceObject = {
codeInstance: dataToExpandToCheck[i].codeInstance,
schemes: schemesArray
};
instanceArray.push(instanceObject);
platformObject = {
codePlatform: dataToExpandToCheck[i].codePlatform,
instances: instanceArray
};
newDataArray.push(platformObject);
}
} else {
instanceObject = {
codeInstance: dataToExpandToCheck[i].codeInstance,
schemes: [
{
codeScheme: dataToExpandToCheck[i].codeScheme,
tables: [
{
codeTable:
dataToExpandToCheck[i].codeTable,
columns: dataToExpandToCheck[i].columns
}
]
}
]
};
instanceArray.push(instanceObject);
platformObject = {
codePlatform: dataToExpandToCheck[i].codePlatform,
instances: instanceArray
};
newDataArray.push(platformObject);
}
} else {
platformObject = {
codePlatform: dataToExpandToCheck[i].codePlatform,
instances: [
{
codeInstance: dataToExpandToCheck[i].codeInstance,
schemes: [
{
codeScheme:
dataToExpandToCheck[i].codeScheme,
tables: [
{
codeTable:
dataToExpandToCheck[i]
.codeTable,
columns:
dataToExpandToCheck[i].columns
}
]
}
]
}
]
};
newDataArray.push(platformObject);
}
}
}
let resultArray = newDataArray.reduce((o, i) => {
if (!o.find((v) => v.codePlatform == i.codePlatform)) {
o.push(i);
}
return o;
}, []);
setRestructuredDataToSend(resultArray);
};
Ответы (2 шт):
Пример где используется временный json для организации данных а затем преобразует его в желаемый формат используя Object.entries()
let dataToExpandToCheck = [
{
codePlatform: 'Platform 1',
codeInstance: 'Instance 1',
codeScheme: 'Scheme 1',
codeTable: 'Table 1',
columns: [],
},
{
codePlatform: 'Platform 1',
codeInstance: 'Instance 1',
codeScheme: 'Scheme 1',
codeTable: 'Table 2',
columns: [],
},
{
codePlatform: 'Platform 1',
codeInstance: 'Instance 1',
codeScheme: 'Scheme 2',
codeTable: 'Table 1',
columns: [],
},
{
codePlatform: 'Platform 1',
codeInstance: 'Instance 2',
codeScheme: 'Scheme 1',
codeTable: 'Table 1',
columns: [],
},
{
codePlatform: 'Platform 2',
codeInstance: 'Instance 1',
codeScheme: 'Scheme 1',
codeTable: 'Table 1',
columns: [],
},
];
// platform -> instance -> schema -> table
const tempObject = {};
// 1. Заполняем объект
dataToExpandToCheck.forEach(({ codePlatform, codeInstance, codeScheme, codeTable, columns }) => {
tempObject[codePlatform] ??= {};
tempObject[codePlatform][codeInstance] ??= {};
tempObject[codePlatform][codeInstance][codeScheme] ??= {};
tempObject[codePlatform][codeInstance][codeScheme][codeTable] = columns;
});
// 2. Преобразуем объект в массив нужной структуры
const restructureFinalDataToSend = Object.entries(tempObject).map(([codePlatform, instances]) => ({
codePlatform,
instances: Object.entries(instances).map(([codeInstance, schemes]) => (
{
codeInstance,
schemes: Object.entries(schemes).map(([codeScheme, tables]) => (
{
codeScheme,
tables: Object.entries(tables).map(([codeTable, columns]) => (
{
codeTable,
columns,
}
)),
}
)),
}
)),
}));
console.log(JSON.stringify(restructureFinalDataToSend, null, 2));
Помогите, пожалуйста, переструктурировать массив.
Предложу еще вот такое решение... Все делается в один проход.
console.log(test(data()))
//
function test(arr){
const def = [
['codePlatform', 'instances'],
['codeInstance', 'schemes'],
['codeScheme', 'tables'],
]
return arr.reduce((res, obj) => (
def.reduce(gen(res.m, obj), res.a).push({
codeTable: obj.codeTable,
columns: obj.columns
}),
res
), {a: [], m: new Map}).a
}
//
function gen(m, obj){
const ak = []
const fn = ([key, name], trg) => {
ak.push(obj[key])
let k = ak.join('.')
let o
if (m.has(k)) {
o = m.get(k)
} else {
o = {
[key]: obj[key],
[name]: []
}
m.set(k, o)
trg.push(o)
}
return o[name]
}
return (t, a) => fn(a, t)
}
//
function data(){
return [
{
codePlatform: 'Platform 1',
codeInstance: 'Instance 1',
codeScheme: 'Scheme 1',
codeTable: 'Table 1',
columns: []
},
{
codePlatform: 'Platform 1',
codeInstance: 'Instance 1',
codeScheme: 'Scheme 1',
codeTable: 'Table 2',
columns: []
},
{
codePlatform: 'Platform 1',
codeInstance: 'Instance 1',
codeScheme: 'Scheme 2',
codeTable: 'Table 1',
columns: []
},
{
codePlatform: 'Platform 1',
codeInstance: 'Instance 2',
codeScheme: 'Scheme 1',
codeTable: 'Table 1',
columns: []
},
{
codePlatform: 'Platform 2',
codeInstance: 'Instance 1',
codeScheme: 'Scheme 1',
codeTable: 'Table 1',
columns: []
},
]
}