我认为在filter nested tree object without losing structure
之前曾有人问过我但是我要寻找的却与此相反。
对于JSON数据
var items = [
{
name: "a1",
id: 1,
children: [{
name: "a2",
id: 2,
children: [{
name: "a3",
id: 3
}]
},
{
name: "b2",
id: 5,
children: [{
name: "a4",
id: 4
}]
}]
}
];
我们需要过滤器,以便您搜索a2
。它应该返回以下内容
var items = [
{
name: "a1",
id: 1,
children: [{
name: "a2",
id: 2,
children: [{
name: "a3",
id: 3
}]
}]
}
];
即该树路径中的所有节点(从根到叶节点)。
有什么想法要在nodejs / javascript中实现吗?
谢谢
答案 0 :(得分:0)
按照我的示例,您可以更改代码以适合您的作品:
var items = [
{
name: "a1",
id: 1,
children: [{
name: "a2",
id: 2,
children: [{
name: "a3",
id: 3
}]
},
{
name: "b2",
id: 5,
children: [{
name: "a4",
id: 4
}]
}]
}
];
//console.log(items);
//first, add depth (of each element) to array items
var depths = items;
//structure of path = [[0,length_1st],[1,length_2nd],[2,length_3rd],[3,length_4th],...,[last,length_last]]
var path = [];
//for first value of path
path.push([0,depths.length]);
//test to add depth for depths:
depths.map(function add_depth(current){
current['depth'] = path[path.length-1][0];
if(current.children){
//continue to array children
path.push([path[path.length-1][0]+1,current.children.length]);
current.children.map(add_depth);
}else{
//get back of path
while(path.length>1 && path[path.length-1][1]<2){
path.pop();
}
//decrease length path[...[x,length]]
path[path.length-1][1]--;
};
});
//console.log(depths);
// has depth in array depths, now is function for search in array depths
function search_name(str){
let path_result = [];
let flagExit = false;
depths.findIndex(function find_name(current,index){
if (flagExit){
return;
};
if(current.name===str){
//finish at here
path_result[current.depth] = index;
flagExit = true;
return;
}else{
if(current.children){
path_result[current.depth] = index;
current.children.findIndex(find_name);
};
};
});
return path_result;
};
var name_to_search = "a3";
var path_end = search_name(name_to_search); //console.log(path_end);
//show result from path_end:
var result = [];
var self_items, self_result;
if (path_end){
for(let i=0;i<path_end.length;i++){
if(i===0){
result[i] = {};
result[i]['name'] = items[path_end[i]].name;
result[i]['id'] = items[path_end[i]].id;
if(i === path_end.length-1){
//just the first result
result[i]['children'] = items[path_end[i]].children;
}else{
result[i]['children'] = [];
self_items = items[path_end[i]].children;
self_result = result[i]['children'];
};
}else{
if(i !== path_end.length-1){
//not to the end
self_result[0] = {};
self_result[0]['name'] = self_items[path_end[i]].name;
self_result[0]['id'] = self_items[path_end[i]].id;
self_result[0]['children'] = [];
self_items = self_items[path_end[i]].children;
self_result = self_result[0]['children'];
}else{
//to the end, check for the children end
self_result[0] = {};
self_result[0]['name'] = self_items[path_end[i]].name;
self_result[0]['id'] = self_items[path_end[i]].id;
if(self_items[path_end[i]].children){
self_result[0]['chidren'] = self_items[path_end[i]].children;
};
//check again the searching, if not match the name_to_search, set result to empty!
if(self_result[0]['name'] !== name_to_search){
result = [];
}
};
}
};
}else{
result = [];
}
console.log(result);
答案 1 :(得分:0)
以下解决方案使用object-scan。
注意:(1)输入未突变(2)期望输入object-scan
形式的行为良好。
如果性能很重要,则可以(1)分隔breakFn
的编译和搜索部分,然后(2)将context.length !== 0
与{ {1}}。
const objectScan = require('object-scan');
const finder = (name, input) => objectScan(['**(^children$).name'], {
useArraySelector: false,
filterFn: ({ key, value, context, parents }) => {
if (value !== name || context.length !== 0) {
return;
}
const result = [];
let cur = result;
for (let idx = 0; idx < key.length - 1; idx += 1) {
const segment = key[idx];
if (idx % 2 === 0) {
cur.push({ ...parents[parents.length - 1 - idx][segment] });
cur = cur[0];
} else {
cur[segment] = [];
cur = cur[segment];
}
}
context.push(result);
}
})(input, [])[0];
const items = [{
name: 'a1',
id: 1,
children: [{
name: 'a2',
id: 2,
children: [{
name: 'a3',
id: 3
}]
}, {
name: 'b2',
id: 5,
children: [{
name: 'a4',
id: 4
}]
}]
}];
console.log(JSON.stringify(finder('a2', items)));
// => [{"name":"a1","id":1,"children":[{"name":"a2","id":2,"children":[{"name":"a3","id":3}]}]}]