修改对象数组的有效方法



我有一个需要重新格式化的对象。输入数组如下所示。我想用一种比使用嵌套循环更好的方式重新格式化它

[{
CategoryId,
CategoryName,
CustomerDescription_c,
CategoryShortName,
CategoryCode,
subcomponents: {
items: [
{
CategoryId,
CategoryName,
CustomerDescription_c,
CategoryShortName,
CategoryCode
}
]
}
}]

我想将这个对象数组操作成这种格式。

[{
CategoryId,
CategoryName,
CustomerDescription_c,
CategoryShortName,
CategoryCode,
ParentLevel,
hasChildren,
value // to populate conditionally if above corresponding object does not have subcomponent 
children :  [
{
CategoryId,
CategoryName,
CustomerDescription_c,
CategoryShortName,
CategoryCode,
value : 'Parent CategoryId',to populate conditionally if above corresponding parent object has subcomponent
ParentLevel
}
]
}]

为了做到这一点,我有下面的函数,我使用嵌套循环,但想知道是否有更好的算法来做同样的事情

function (data) {
let formattedData = [];
if (data) {
let arr = data;
for (let i = 0, len = arr.length; i < len; i++) {
let category = {
CategoryId: arr[i].CategoryId,
CategoryName: arr[i].CategoryName,
CustomerDescription_c: arr[i].CustomerDescription_c,
CategoryShortName: arr[i].CategoryShortName,
CategoryCode: arr[i].CategoryCode,
ParentLevel: true
};
if (arr[i].subcomponents) {
let childrenArray = arr[i].subcomponents.items;
category.children = [];
category.hasChildren = true;
for (let j = 0, len = childrenArray.length; j < len; j++) {
category.children.push({
CategoryId: childrenArray[j].CategoryId,
CategoryName: childrenArray[j].CategoryName,
CustomerDescription_c: childrenArray[j].CustomerDescription_c,
CategoryShortName: childrenArray[j].CategoryShortName,
value: arr[i].CategoryId,
CategoryCode: childrenArray[j].CategoryCode,
ParentLevel: false
});
}
} else {
category.value = arr[i].CategoryId;
category.hasChildren = false;
}
formattedData.push(category);
}
}
return formattedData;
};

您可以使用递归函数transform对其输入t-进行简单的类型分析

function transform (t, parentId = null) {
switch (t?.constructor) {
case Array:
return t.map(v => transform(v, parentId))
case Object:
const { subcomponents = {}, ...node } = t
return {
...node,
parentId,
hasChildren: Boolean(subcomponents.items),
children: transform(subcomponents.items ?? [], t.id)
}
default:
throw Error()
}
}

给定一些启动data-

const data = [
{ id: 1, category: "a", subcomponents: {
items: [
{ id: 2, category: "a1", subcomponents: {
items: [
{ id: 3, category: "a1z" }
]
}},
{ id: 1, category: "a2", subcomponents: {
items: [
{ id: 4, category: "a2x" },
{ id: 5, category: "a2y" }
]
}},
]
}},
{ id: 6, category: "b", subcomponents: {
items: [
{ id: 7, category: "bb", subcomponents: {
items: [
{ id: 8, category: "bbb", subcomponents: {
items: [
{ id: 9, category: "bbbb" }
]
}},
]
}},
]
}},
{ id: 10, category: "z", subcomponents: {
items: [
{ id: 11, category: "z" }
]
}},
]
transform(data)
[
{
"id": 1,
"category": "a",
"parentId": null,
"hasChildren": true,
"children": [
{
"id": 2,
"category": "a1",
"parentId": 1,
"hasChildren": true,
"children": [
{
"id": 3,
"category": "a1z",
"parentId": 2,
"hasChildren": false,
"children": []
}
]
},
{
"id": 1,
"category": "a2",
"parentId": 1,
"hasChildren": true,
"children": [
{
"id": 4,
"category": "a2x",
"parentId": 1,
"hasChildren": false,
"children": []
},
{
"id": 5,
"category": "a2y",
"parentId": 1,
"hasChildren": false,
"children": []
}
]
}
]
},
{
"id": 6,
"category": "b",
"parentId": null,
"hasChildren": true,
"children": [
{
"id": 7,
"category": "bb",
"parentId": 6,
"hasChildren": true,
"children": [
{
"id": 8,
"category": "bbb",
"parentId": 7,
"hasChildren": true,
"children": [
{
"id": 9,
"category": "bbbb",
"parentId": 8,
"hasChildren": false,
"children": []
}
]
}
]
}
]
},
{
"id": 10,
"category": "z",
"parentId": null,
"hasChildren": true,
"children": [
{
"id": 11,
"category": "z",
"parentId": 10,
"hasChildren": false,
"children": []
}
]
}
]

运行下面的演示,在您自己的浏览器-中验证结果

const data = [
{ id: 1, category: "a", subcomponents: {
items: [
{ id: 2, category: "a1", subcomponents: {
items: [
{ id: 3, category: "a1z" }
]
}},
{ id: 1, category: "a2", subcomponents: {
items: [
{ id: 4, category: "a2x" },
{ id: 5, category: "a2y" }
]
}},
]
}},
{ id: 6, category: "b", subcomponents: {
items: [
{ id: 7, category: "bb", subcomponents: {
items: [
{ id: 8, category: "bbb", subcomponents: {
items: [
{ id: 9, category: "bbbb" }
]
}},
]
}},
]
}},
{ id: 10, category: "z", subcomponents: {
items: [
{ id: 11, category: "z" }
]
}},
]
function transform (t, parentId = null) {
switch (t?.constructor) {
case Array:
return t.map(v => transform(v, parentId))
case Object:
const { subcomponents = {}, ...node } = t
return {
...node,
parentId,
hasChildren: Boolean(subcomponents.items),
children: transform(subcomponents.items ?? [], t.id)
}
default:
throw Error()
}
}
console.log(JSON.stringify(transform(data), null, 2))
.as-console-wrapper { min-height: 100%; top: 0; }

我将value重命名为parentId,因为它更具描述性。我建议不要使用hasChildren: Boolean键/值,因为它是派生状态,不需要存储在每个节点中。我们可以通过检查.children属性来知道任何特定节点是否具有子节点。

最新更新