我有以下对象。我想要做的是提出一个函数,该函数将指定给定对象是否是id的父元素的后代。例如,我想这样做:欢迎lodash。
isThisDescendant(7,1) //true
isThisDescendant(1,7) //false
isThisDescendant(7,3) //false
isThisDescendant(3,2) //true
object = {
children : [
{
name: 'a',
id: 1,
children: [
{
name: 'b',
id: 2,
children: [
{
name: 'c',
id: 3,
children: []
},
{
name: 'cc',
id: 4,
children: []
}
]
},
{
name: 'ba',
id: 6,
children: [
{
name: 'c',
id: 8,
children: []
},
{
name: 'cd',
id: 7,
children: []
}
]
}
]
},
{
name: 'bb',
id: 10,
children: []
}
]
}
答案 0 :(得分:1)
可能有点过于冗长,但有一些输入参数可以像这样做
function findNodeById( branch, id ) {
if (!branch) {
return null;
}
if (branch.id === id) {
return branch;
}
for (let child of branch.children) {
let result = findNodeById( child, id );
if (result) {
return result;
}
}
return null;
}
function isThisDescendant(tree, childId, parentId ) {
const parent = findNodeById( tree, parentId );
if (!parent) {
return false;
}
const child = findNodeById( parent, childId );
return child !== null;
}
const branch = {
children : [
{
name: 'a',
id: 1,
children: [
{
name: 'b',
id: 2,
children: [
{
name: 'c',
id: 3,
children: []
},
{
name: 'cc',
id: 4,
children: []
}
]
},
{
name: 'ba',
id: 6,
children: [
{
name: 'c',
id: 8,
children: []
},
{
name: 'cd',
id: 7,
children: []
}
]
}
]
},
{
name: 'bb',
id: 10,
children: []
}
]
};
console.log(isThisDescendant(branch, 7,1)); //true
console.log(isThisDescendant(branch, 1,7)) //false
console.log(isThisDescendant(branch, 7,3)) //false
console.log(isThisDescendant(branch, 3,2)) //true

答案 1 :(得分:1)
您可以创建将在数组上使用forEach
循环的递归函数,并检查在任何级别上看到第二个参数后是否存在第一个参数。
var object = {"children":[{"name":"a","id":1,"children":[{"name":"b","id":2,"children":[{"name":"c","id":3,"children":[]},{"name":"cc","id":4,"children":[]}]},{"name":"ba","id":6,"children":[{"name":"c","id":8,"children":[]},{"name":"cd","id":7,"children":[]}]}]},{"name":"bb","id":3,"children":[]}]}
function isThisDescendant(a, b) {
var r = false;
function f(a, b, data = object, p = false) {
if (Array.isArray(data)) {
data.forEach(function(o) {
if (p && a == o.id) r = true;
else f(a, b, o.children, !p ? b == o.id : p)
})
} else f(a, b, data.children, p)
}
f(a, b)
return r
}
console.log(isThisDescendant(7, 1)) //true
console.log(isThisDescendant(1, 7)) //false
console.log(isThisDescendant(7, 3)) //false
console.log(isThisDescendant(3, 2)) //true
答案 2 :(得分:0)
有许多解决方案,但为了提高效率,需要采取某些假设:
这是一次性事情还是需要不断查询?
如果是一次性操作,那么您可以通过简单的广度优先搜索来寻找父级,然后检查其子级是否包含您正在寻找的id
。这是O(n)。
如果不是,那么您应该构建一个查找表(id, instance)
,然后使用该表查找您的父项并进行检查。这或多或少是O(1)到O(log n),因为子尺寸小于整个尺寸的尺寸。
children
数组是否已排序?
如果对数组进行了排序,一旦拥有父实例,就可以对children数组执行二进制搜索,以进一步优化它。
答案 3 :(得分:0)
这里需要执行两个步骤 - 抓取树以找到“容器”,然后从容器中向下爬行以找到后代。
const object = {
children : [
{
name: 'a',
id: 1,
children: [
{
name: 'b',
id: 2,
children: [
{
name: 'c',
id: 3,
children: []
},
{
name: 'cc',
id: 4,
children: []
}
]
},
{
name: 'ba',
id: 6,
children: [
{
name: 'c',
id: 8,
children: []
},
{
name: 'cd',
id: 7,
children: []
}
]
}
]
},
{
name: 'bb',
id: 10,
children: []
}
]
}
function isThisDescendant( descendentId, containerId, root = object, foundContainer = false ) {
if ( root.id === descendentId && foundContainer ) return true; //found it inside the container
if ( root.id === descendentId && !foundContainer ) return false; //we found the descendent before the container
//recurse down to children
const newFoundContainer = foundContainer || root.id === containerId;
const childResults = root.children.map(
child => isThisDescendant( descendentId, containerId, child, newFoundContainer )
);
return or( childResults ); //return true if any of the children hits
}
//returns true if any items in the array are true
function or( values ) {
return Boolean( values.filter( Boolean ).length );
}
console.log( isThisDescendant(7,1) ); //true
console.log( isThisDescendant(1,7) ); //false
console.log( isThisDescendant(7,3) ); //false
console.log( isThisDescendant(3,2) );//true
一些注意事项:
root = object
)开始,foundContainer
变量始于false
,因此我们寻找容器第一foundContainer
存储为持久状态 - 最好每次都记下要传递的内容并保持递归“纯粹”(没有状态/副作用)答案 4 :(得分:0)
这个问题涉及一个常见问题:在树中找到一个“喜欢”结构的节点。这总是涉及递归。
您可以编写一个函数isDescendant(rootObj, valueA, valueB)
。它看起来像这样:
function isDescendant(rootObj, parentId, childId) {
const parentNode = findChildren(rootObj, parentId); // Find the parent node
if (!parentNode) return false;
return !!findChildren(parentNode, childId); // Find the child node
}
function findChildren(obj, id) {
if (obj.id === id) return obj;
if (obj.children) return obj.children.find(c => findChildren(c, id));
}