我有一个如下结构的数组:
var persons= [{name: 'John',
id: 1,
children :[{name :'John Jr',
id: 11,
children :[{name: 'John Jr Jr'
id: 111}]
},
{name :'Jane'
id: 12}]
},
{name:'Peter',
id :2
},
...]
它基本上是一个对象数组,对象是人,每个人可能有任意数量的后代,这些后代由他们自己的人物对象组成。每个人的后代数量都是未知的。
我想要实现的是以这种方式构建地图:
var personsMap =[1 : 'John',
11: 'John > John Jr',
111 : 'John > John Jr > John Jr Jr',
12: 'John > Jane',
...
]
这是每个路径的每个可能组合的地图,因此通过按人的身份查询地图,它应该返回它的父母>的字符串。祖父母> ...
我正在尝试递归地构建这个地图,所以到目前为止我尝试过:
var personsMap = {};
function buildParentsMap (persons){
$.each (persons, function(ndx, person){
if(person.children && person.children.length > 0){
buildParentsMap(person.children);
}
personsMap[person.id] = person.name;
});
console.log(personsMap);
}
但是这会输出以下内容:
[1 : 'John',
11: 'John Jr',
111 'John Jr Jr',
12: 'Jane',
...]
这是所有的名字,但没有按照我上面解释的方式连接。 我怎样才能做到这一点?感谢
答案 0 :(得分:1)
您可以使用此版本的功能(ES6代码):
function buildParentsMap(persons, path = []) {
return (persons || []).reduce( (acc, person) =>
acc.concat({ [person.id]: path.concat(person.name).join(' > ') },
buildParentsMap(person.children, path.concat(person.name)))
, []);
}
// Sample data
const persons=[{name: 'John',id: 1,children : [{name :'John Jr',id: 11,children :[{name: 'John Jr Jr',id: 111}]}, {name :'Jane',id: 12}]}, {name:'Peter', id :2 }];
const result = buildParentsMap(persons);
console.log(result);

.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 1 :(得分:1)
原始buildParentsMap
函数的问题在于,尽管它成功地进行了递归调用以将每个人添加到地图中,但它并没有以任何方式构建以跟踪每个孩子的祖先。在buildParentsMap
上调用John Jr Jr
时,它只知道有关已传入其中的特定数组的信息,如下所示:[{name: 'John Jr Jr', id: 111}]
。
解决此问题的一种方法是向buildParentsMap
函数添加第二个参数,以跟踪需要将哪些祖先(如果有)添加到当前添加到地图的任何人身上。例如:
var personsMap = {};
// Accept an optional "ancestors" argument in each function call
// so we know what prefix to append onto each child
function buildParentsMap (persons, ancestors){
// If no ancestors, nothing needs to be appended
// so set to empty string
if( !ancestors ) ancestors = "";
// Loop through all people in the array
for(let idx in persons){
let person = persons[idx];
if(person.children && person.children.length > 0){
// If this person has children, make a recursive call on the
// children. Include the current person as an ancestor
let prefix = ancestors + person.name + " > ";
buildParentsMap(person.children, prefix);
}
personsMap[person.id] = ancestors + person.name;
}
}
如果我们使用您的示例数组测试它:
var personsExample = [
{ name: 'John',
id: 1,
children: [
{
name: 'John Jr',
id: 11,
children: [
{
name: 'John Jr Jr',
id: 111
}
]
},
{
name: 'Jane',
id: 12
}
]
},
{
name:'Peter',
id: 2
}
];
buildParentsMap(personsExample);
console.log(personsMap);
输出现在如下所示:
{ 1: 'John',
2: 'Peter',
11: 'John > John Jr',
12: 'John > Jane',
111: 'John > John Jr > John Jr Jr' }