给出以下数据结构:
[
{
"name":"root",
"children":[
{
"name":"de",
"children":[
{
"name":"de",
"children":[
{
"name":"project-1",
"children":[
]
},
{
"name":"project-2",
"children":[
]
}
]
}
]
}
]
}
]
预期:
[
{
"name":"project-1",
"children":[
]
},
{
"name":"project-2",
"children":[
]
}
]
如果只有一个孩子,我想删除一个关卡。在此示例中,我想要一个新数组,其中仅包含“ root”级别的子级,而没有root本身。
我会用reduce
来做到这一点,但仍然无法将reduce
与递归结合起来。有什么想法吗?
答案 0 :(得分:0)
之后,您可以简单地使用map和flatten数组。
.map(o => o.children).flat()
编辑:找出真实问题后,更新答案
仍然可以以递归的方式使用map和flatten逻辑。
function removeSingleChildElms (o) {
if (!o.children) return
if (o.children.length === 1) {
return o.children.map(removeSingleChildElms).flat()
} else {
return o.children
}
}
EDIT2: 一些解释:问题是将对象数组转换为不同对象的数组。我不选择减少,因为问题不关心同级元素之间的关系/逻辑。这只是为了进行转换,因此地图将足以正常工作。
问题要求“跳过”有1个孩子的对象。这是重复出现的部分,这意味着:如果看到满足此条件的对象,则可以进行更深入的映射。在任何其他有效条件下,孩子都保持不变(否则)
答案 1 :(得分:0)
通过将任务分为两部分,可以轻松进行树转换:
要转换单个节点,我们编写transform1
transformAll
const transform1 = ({ children = [], ...node }) =>
children.length === 0 // leaf
? [ node ]
: children.length === 1 // singleton
? transform1 (...children)
: transformAll (children) // default
要转换节点数组,我们写transformAll
-
const transformAll = (arr = []) =>
arr .flatMap (transform1)
如您所见,transformAll
调用transform1
,也调用transformAll
。这种技术称为mutual recursion,是处理递归数据结构(如您在问题中提出的结构)的好方法。
为了确保我们的功能正常工作,我修改了树以包含更多数据方案。请注意,我们的程序适用于具有children
属性的任何节点。所有其他属性都显示在结果中-
const data =
[ { name: "a"
, children:
[ { name: "a.a"
, children:
[ { name: "a.a.a"
, children: []
}
, { name: "a.a.b"
, foo: 123
, children: []
}
]
}
]
}
, { name: "b"
, children:
[ { name: "b.a"
, children:
[ { name: "b.a.a"
, children: []
}
, { name: "b.a.b"
, children: []
}
]
}
, { name: "b.b"
, children: []
}
]
}
, { name: "c"
, children: []
}
]
我们可以对您的数据运行transformAll
来转换所有个节点-
transformAll (data)
// [ { name: 'a.a.a' }
// , { name: 'a.a.b', foo: 123 }
// , { name: 'b.a.a' }
// , { name: 'b.a.b' }
// , { name: 'b.b' }
// , { name: 'c' }
// ]
或者要转换单个节点,我们称为transform1
-
transform1 (data[0])
// [ { name: 'a.a.a' }
// , { name: 'a.a.b', foo: 123 }
// ]
transform1 (data[2])
// [ { name: 'c' } ]
展开以下代码段,以在您自己的浏览器中验证结果-
const data =
[ { name: "a"
, children:
[ { name: "a.a"
, children:
[ { name: "a.a.a"
, children: []
}
, { name: "a.a.b"
, foo: 123
, children: []
}
]
}
]
}
, { name: "b"
, children:
[ { name: "b.a"
, children:
[ { name: "b.a.a"
, children: []
}
, { name: "b.a.b"
, children: []
}
]
}
, { name: "b.b"
, children: []
}
]
}
, { name: "c"
, children: []
}
]
const transform1 = ({ children = [], ...node }) =>
children.length === 0 // leaf
? [ node ]
: children.length === 1 // singleton
? transform1 (...children)
: transformAll (children) // default
const transformAll = (arr = []) =>
arr .flatMap (transform1)
console .log (transformAll (data))
// [ { name: 'a.a.a' }
// , { name: 'a.a.b', foo: 123 }
// , { name: 'b.a.a' }
// , { name: 'b.a.b' }
// , { name: 'b.b' }
// , { name: 'c' }
// ]