Я бы порекомендовал начать с универсальной c функции отображения объектов. Для этого требуется ввод объекта o
и преобразование t
-
const identity = x =>
x
const mapObject = (o = {}, t = identity) =>
Object.fromEntries(Object.entries(o).map(([ k, v ]) => [ k, t(v) ]))
. Затем создайте свою функцию рекурсивного сопоставления объектов, используя вашу мелкую функцию. Для преобразования требуется объект o
и функция преобразования t
-
const recMapObject = (o = {}, t = identity) =>
mapObject // <-- using mapObject
( o
, node =>
Array.isArray(node) // <-- recur arrays
? node.map(x => recMapObject(t(x), t))
: Object(node) === node // <-- recur objects
? recMapObject(t(node), t)
: t(node)
)
Теперь вы создаете преобразование объекта, уникальное для вашей программы, с помощью нашей функции рекурсивного сопоставления объектов. Для этого требуются сложные вложенные данные graph
, uid
для сопоставления и преобразование для применения к сопоставленному узлу t
-
const transformAtUid = (graph = {}, uid = "", t = identity) =>
recMapObject // <-- using recMapObject
( graph
, (node = {}) =>
node.uid === uid // if uid matches,
? { ...node, data: t(node.data) } // then transform node.data,
: node // otherwise no change
)
Вышеуказанный шаг важен, поскольку он распутывает c logi c о node.uid
и node.data
от остальной части универсального c кода преобразования объекта.
Теперь мы вызываем нашу функцию на входе data
, чтобы преобразовать узлы, совпадающие с node.uid
равными "bcd"
, используя пример преобразования -
const result =
transformAtUid
( data // <-- input
, "bcd" // <-- query
, node => ({ ...node, changed: "x" }) // <-- transformation
)
console.log(result)
Выходные данные -
{
"uid": "abc",
"layout": {
"rows": [
{
"columns": [
{
"blocks": [
{
"uid": "bcd",
"data": {
"content": "how are you?",
"changed": "x" // <-- transformed
}
}
]
}
// ...
}
Разверните фрагмент ниже, чтобы проверить результаты в своем собственном браузере -
const identity = x =>
x
const mapObject = (o = {}, t = identity) =>
Object.fromEntries(Object.entries(o).map(([ k, v ]) => [ k, t(v) ]))
const recMapObject = (o = {}, t = identity) =>
mapObject // <-- using mapObject
( o
, node =>
Array.isArray(node) // <-- recur arrays
? node.map(x => recMapObject(t(x), t))
: Object(node) === node // <-- recur objects
? recMapObject(t(node), t)
: t(node) // <-- transform
)
const transformAtUid = (graph = {}, uid = "", t = identity) =>
recMapObject
( graph
, (node = {}) =>
node.uid === uid
? { ...node, data: t(node.data) }
: node
)
const data =
{uid:"abc",layout:{rows:[{columns:[{blocks:[{uid:"bcd",data:{content:"how are you?"}}]},{blocks:[{uid:"cde",data:{content:"how are you?"}}]},],},{columns:[{blocks:[{uid:"def",data:{content:"how are you?"}}]}],}]}}
const result =
transformAtUid
( data
, "bcd"
, node => ({ ...node, changed: "x" })
)
console.log(JSON.stringify(result, null, 2))
В вашем исходном вопросе я вижу, что у вас есть массив объектов для изменения -
// your original
this.sections = [ {...}, {...}, ... ]
Для использования recMapObject
и transformAtUid
с массивом объектов, мы можем использовать Array.prototype.map
-
this.sections = this.sections.map(o => transformAtUid(o, "bcd", ...))