function Node()
{
}
Node.prototype.id = null;
Node.prototype.prev = null;
Node.prototype.next = null;
Node.prototype.filter = function($mapFilter){
let i;
let arr, arrNext = [];
for(i=0; i<this.next.length; iPP)
{
arr = this.next[i].filter($mapFilter);
if(arr !== null)
arrNext.push(arr);
}
if(arrNext.length <= 0 && (this.id in $mapFilter) === false)
return null;
return {
id : this.id
,pid : (this.prev === null)?Tree.ROOT_ID:this.prev.id
,children : arrNext
};
};
function Tree()
{
this.mapRoot = [];
this.mapNode = [];
}
Tree.ROOT_ID = 0;
Tree.prototype.mapRoot = null;
Tree.prototype.mapNode = null;
Tree.prototype.add = function($ndi){
let nodeThis, nodePrev;
if($ndi.id in this.mapNode === false)
{
nodeThis = new Node();
nodeThis.id = $ndi.id;
nodeThis.prev = null;
nodeThis.next = [];
this.mapNode[$ndi.id] = nodeThis;
}
else
nodeThis = this.mapNode[$ndi.id];
nodePrev = null;
if($ndi.pid !== Tree.ROOT_ID)
{
if($ndi.pid in this.mapNode === false)
{
nodePrev = new Node();
nodePrev.id = $ndi.pid;
nodePrev.prev = null;
nodePrev.next = [];
this.mapNode[$ndi.pid] = nodePrev;
}
else
nodePrev = this.mapNode[$ndi.pid];
nodePrev.next.push(nodeThis);
}
nodeThis.prev = nodePrev;
if(nodePrev !== null && nodePrev.id in this.mapRoot === false && nodePrev.prev === null)
this.mapRoot[nodePrev.id] = nodePrev;
if(nodeThis.id in this.mapRoot === true && nodeThis.prev !== null)
delete this.mapRoot[nodeThis.id];
};
Tree.prototype.filter = function($arrFilter){
let mapFilter = {};
for(i=0; i<$arrFilter.length; iPP)
mapFilter[$arrFilter[i]] = $arrFilter[i];
let data = [];
let id;
for(id in this.mapRoot)
{
if(this.mapRoot.hasOwnProperty(id) === false)
continue;
data.push(this.mapRoot[id].filter(mapFilter));
}
return data;
};
let arrNode = [
{ id: 4, pid: 3 },
{ id: 3, pid: 2 },
{ id: 1, pid: 0 },
{ id: 2, pid: 1 },
{ id: 5, pid: 3 },
{ id: 6, pid: 2 },
{ id: 7, pid: 1 },
{ id: 8, pid: 10 },
{ id: 9, pid: 8 },
{ id: 10, pid: 11 },
];
let i;
let tree = new Tree();
//
for(i=0; i<arrNode.length; iPP)
tree.add(arrNode[i]);
//
let data = tree.filter([3,7,9]);
console.log(JSON.stringify(data, null, ' '));
let all = [
{ id: 4, pid: 3 },
{ id: 3, pid: 2 },
{ id: 1, pid: 0 },
{ id: 2, pid: 1 },
{ id: 5, pid: 3 },
{ id: 6, pid: 2 },
{ id: 7, pid: 1 },
{ id: 8, pid: 10 },
{ id: 9, pid: 8 },
{ id: 10, pid: 11 },
]
// id
let getPid = id => {
let parent = {}
all.forEach(obj => {
if (obj.id == id) {
parent = obj
}
})
return parent
}
// pid
let getParents = (id, parents = []) => {
if (!id) {
return parents
}
if (parents.indexOf(id) < 0) {
parents.push(id)
}
let pid = getPid(id).pid
if (parents.indexOf(pid) > -1) {
return parents
} else if (pid == 0) {
// parents.push(id)
return parents
} else {
return getParents(pid, parents)
}
}
let ids = [3, 7, 9]
// id
let parents = []
ids.forEach(id => {
parents = getParents(id, parents)
})
console.log(parents)
// [ 3, 2, 1, 7, 9, 8, 10, 11 ]
// hash key
rec = (id, hash) => {
let obj = hash[id]
if (obj.pid in hash) {
if (!('children' in hash[obj.pid])) {
hash[obj.pid]['children'] = {}
}
hash[obj.pid]['children'][obj.id] = JSON.parse(JSON.stringify(obj))
return rec(obj.pid, hash)
} else {
return hash
}
}
// parents id
let hash = {}
all.forEach(obj => {
let id = obj.id
if (parents.indexOf(id) > -1) {
hash[id] = JSON.parse(JSON.stringify(obj))
}
})
let keys = Object.keys(hash)
keys.forEach(key => {
hash = rec(key, hash)
})
let tree = {}
keys.forEach(key => {
if (!(hash[key].pid in hash)) {
tree[key] = hash[key]
}
})
console.log(tree)
results obtained
{
"1": {
"id": 1,
"pid": 0,
"children": {
"2": {
"id": 2,
"pid": 1,
"children": {
"3": {
"id": 3,
"pid": 2
}
}
},
"7": {
"id": 7,
"pid": 1
}
}
},
"10": {
"id": 10,
"pid": 11,
"children": {
"8": {
"id": 8,
"pid": 10,
"children": {
"9": {
"id": 9,
"pid": 8
}
}
}
}
}
}
in fact, the given data is very suitable for building a node tree. Each different id is a node. The code is as follows
// 1.
nda = arr.map(v => {
return { ...v }
})
// 2.
nda.forEach(v => {
//
v.children = nda.filter(child => child.pid == v.id)
//
v.children == 0 && delete v.children
});
find the root node and get the whole tree print
let root = nda.find(item => item.id == 1)
console.log(JSON.stringify(root, null, 2))
effect
{
"id": 1,
"pid": 0,
"children": [
{
"id": 2,
"pid": 1,
"children": [
{
"id": 3,
"pid": 2,
"children": [
{
"id": 4,
"pid": 3
},
{
"id": 5,
"pid": 3
}
]
},
{
"id": 6,
"pid": 2
}
]
},
{
"id": 7,
"pid": 1
}
]
}
compared with Filter id, the branch is removed as the leaf node first, and then the sibling node of the non-designated id of the same father, which needs to be recursive, as follows
function filterTree(nd, ids) {
// 1.id
if (ids.includes(nd.id)) {
nd.children && delete nd.children
}
if (nd.children) {
for (let i = nd.children.length - 1; i >= 0; i--) {
const element = nd.children[i];
// 2.
if (element.children) {
// 3.
filterTree(element, ids)
} else {
// 4.
if (!(ids.includes(element.id))) {
nd.children.splice(i, 1)
}
}
}
}
return
}
in the end, Filter will be tested as follows, as you want.
filterTree(root, [3, 7])
console.log(JSON.stringify(root, null, 2))
{
"id": 1,
"pid": 0,
"children": [
{
"id": 2,
"pid": 1,
"children": [
{
"id": 3,
"pid": 2
}
]
},
{
"id": 7,
"pid": 1
}
]
}