Answer the question
In order to leave comments, you need to log in
How to extract objects from an array into a new object?
The formattedData
function extracts all c object references from data.default and data.custom and adds an id to them. Also, if the custom data object matches the default data object by id, the function will create a parent property in the custom object from the default data object, and will then remove the matched default object from data.default .
The problem is in the parent property in the user object, the data is not retrieved by links and is not attached to the id. Please help me implement this logic
const data = {
default: [
{
id: "first",
links: [{
name: "testName1",
number: 1
}]
},
{
id: "second",
links: [
{
name: "testName2",
number: 2
},
{
name: "testName2.1",
number: 2.1
}
]
},
{
id: "third",
links: [
{
name: "testName3",
number: 3
},
{
name: "testName3.1",
number: 3.1
},
]
},
],
custom: [
{
id: "first",
links: [{
name: "testName1",
number: 1
}]
},
{
id: "second",
links: [
{
name: "testName2",
number: 2
},
{
name: "testName2.1",
number: 2.1
}
]
},
]
}
function formattedData() {
let defaultData = data.default || []
let customData = data.custom || []
const extractDefaultDataId = defaultData.map(el => el.id)
const extractCustomDataId = customData.map(el => el.id)
// create parent object from default data object
// if custom data object have matched to default data object by id
customData = customData.map((cd) => {
const parent = defaultData
.find(dd => dd.id === cd.id)
return {
...cd,
...(extractDefaultDataId
.includes(cd.id)) && {
parent: {
...parent,
scope: "defaultData"
}
},
}
})
// remove default object from "default" property
// if custom data object have matched to default data object by id
defaultData = defaultData.filter(
dd => !extractCustomDataId.includes(dd.id)
)
// extracting all links which default and custom data has
// and linking them to id
return Object.entries({ defaultData, customData })
.map(([k, v]) => v.map(({ links, ...link }) => links
.map(el => ({
...el,
...link,
scope: `${k}`,
}))))
.flat(2)
}
console.log(formattedData())
[
{
name: "testName3",
number: 3,
id: "third",
scope: "defaultData"
},
{
name: "testName3.1",
number: 3.1,
id: "third",
scope: "defaultData"
},
{
name: "testName1",
number: 1,
id: "first",
parent: {
id: "first",
name: "testName1",
number: 1,
scope: "defaultData"
},
scope: "customData"
},
{
name: "testName2",
number: 2,
id: "second",
parent: {
id: "second",
name: "testName2",
number: 2,
scope: "defaultData"
},
scope: "customData"
},
{
name: "testName2.1",
number: 2.1,
id: "second",
parent: {
id: "second",
name: "testName2.1",
number: 2.1,
scope: "defaultData"
},
scope: "customData"
},
]
Answer the question
In order to leave comments, you need to log in
let customKeys
const items = Array.from(['custom', 'default']).flatMap(group => {
const scope = group + "Data"
// Собираем элементы группы
const items = (data[group] || []).flatMap(({ id, links }) =>
links.map(link => ({...link, id, scope }))
)
const getKey = v => JSON.stringify([v.id, v.number])
if (!customKeys) {
// индексируем ключи кастомных элементов
customKeys = items.reduce((agg, v) =>
Object.assign(agg, {[getKey(v)]: v})
, {})
return items
} else {
// Для ключей, найденных ранее, устанавливаем родителя и отфильтровываем
const defaultIds = []
const defaultItems = items.filter(v => {
const child = customKeys[getKey(v)]
if (child) {
child.parent = v
defaultIds.push(v.id)
} else {
return true
}
})
// Оставляем в data.default лишь элементы с id, не найденные в custom
if (defaultIds.length) {
const idsSet = new Set(defaultIds)
const copy = [...data.default]
data.default.length = 0
data.default.push(...copy.filter(v => !idsSet.has(v.id)))
}
return defaultItems
}
})
console.log(data) // Дата без кастомных ключей в дефолт скоуп
console.log(items) // Результат
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question