根据给定的键和值在深度嵌套的对象数组中添加/更新属性



我有一个深度嵌套的数组,看起来像这样:

const elements = [
{
type: "section",
id: "basic-section",
title: "Basic information",
children: [
{
type: "select",
label: "Entity type",
id: "entity-type",
options: [
{ value: "person", label: "Person" },
{ value: "company", label: "Company" },
{ value: "organisation", label: "Organisation" },
],
},
{
type: "group",
conditions: [
{ type: "isEqual", variable: "entity-type", value: ["person"] },
],
children: [
{ type: "text", label: "First name", id: "entity.firstName" },
{ type: "text", label: "Last name", id: "entity.lastName" },
{ type: "number", label: "Age", id: "entity.age" },
{
type: "select",
label: "Gender",
id: "entity.gender",
defaultValue: "female",
options: [
{ value: "male", label: "Male" },
{ value: "female", label: "Female" },
],
},
],
},
{
type: "group",
conditions: [
{
type: "isEqual",
variable: "entity-type",
value: ["company", "organisation"],
},
],
children: [
{ type: "text", label: "Name", id: "entity.name" },
{ type: "text", label: "Address", id: "entity.address" },
],
},
],
},
];

我正在尝试根据给定的键和值添加和更新属性。

示例 1:将选项添加到entity-type的选项列表

示例 2:将entity.genderdefaultValue更新为male

我目前完成此操作的步骤是:

1(根据id keyid value查找元素

const element = findObject(elements, 'id', 'entity-type');
function findObject(object, key, value) {
if(object.hasOwnProperty(key) && object[key] === value) {
return object;
}
for(let i = 0; i < Object.keys(object).length; i++){
if(typeof object[Object.keys(object)[i]] == "object") {
const o = findObject(object[Object.keys(object)[i]], key, value);
if(o !== null) return o;
}
}
return null;
}

2( 创建新选项

const newOption = { value: 'government', label: 'Government' };

3( 将新选项添加到找到的元素

const updatedElement = Object.assign({}, element, { options: [...element.options, newOption] });

4( 将旧元素替换为更新的元素

const newElementsList = // Stuck

5( 使用更新的元素列表更新状态

setElementsList(newElementsList);

我不明白如何根据键和值将原始元素替换为更新的元素。

有人可以帮助我吗?

不建议这样做,但您可以跟踪父级。找到元素后,使用更新值更新父数据。但是你失去了不变性。

将找到更好的方法并同时更新。

const elements = [{"type":"section","id":"basic-section","title":"Basic information","children":[{"type":"select","label":"Entity type","id":"entity-type","options":[{"value":"person","label":"Person"},{"value":"company","label":"Company"},{"value":"organisation","label":"Organisation"}]},{"type":"group","conditions":[{"type":"isEqual","variable":"entity-type","value":["person"]}],"children":[{"type":"text","label":"First name","id":"entity.firstName"},{"type":"text","label":"Last name","id":"entity.lastName"},{"type":"number","label":"Age","id":"entity.age"},{"type":"select","label":"Gender","id":"entity.gender","defaultValue":"female","options":[{"value":"male","label":"Male"},{"value":"female","label":"Female"}]}]},{"type":"group","conditions":[{"type":"isEqual","variable":"entity-type","value":["company","organisation"]}],"children":[{"type":"text","label":"Name","id":"entity.name"},{"type":"text","label":"Address","id":"entity.address"}]}]}];
// console.log("%j", elements);
function findObject(element, key, value, { parent = null, index = -1 }) {
if (element.hasOwnProperty(key) && element[key] === value) {
return { element: element, parent, index };
}
let keys = Object.keys(element);
for (let i = 0; i < keys.length; i++) {
if (typeof element[keys[i]] == "object") {
const o = findObject(element[Object.keys(element)[i]], key, value, {
parent: element,
index: i,
});
if (o !== null) return o;
}
}
return { element: null };
}
const { element, parent, index } = findObject(
elements,
"id",
"entity-type",
{}
);
const newOption = { value: "government", label: "Government" };
const updatedElement = Object.assign({}, element, {
options: [...element.options, newOption],
});
if (parent && index !== -1) parent[index] = updatedElement;
console.log(JSON.stringify(elements, null, 4));

最新更新