c# - Recursively search nested lists; Returning parent -
this follow post one: recursively search nested lists
i've been attempting modify code resulted allow me return parent item of whatever child located, recursive aspect of function doesn't flow in brain reason.
in perfect world i'd able specify how many parent nodes return, immediate great.
public static accessibletreeitem find(accessibletreeitem node, string name) { if (node == null) return null; if (node.name == name) return node; foreach (var child in node.children) { var found = find(child, name); if (found != null) return found; } return null; }
thanks taking time have look.
edit: so, example, i'd able call find(node, name, parentindex) or similar, pass through value represents number of parent levels item being returned can found at.
edit 2: clarify, able tell function find particular name, , parentindex. function locate node being searched for, , traverse 'tree' specified number of levels, , returning object.
so if called
find(node, "test", 2)
and value being searched at:
node.children[0].children[3].children[2].children[1]
then function should return object located at:
node.children[0].children[3]
aha... try passing down byref (positive) integer called "ancestorcount" (1 parent, 2 grandparent, 3 great-gran-dad, etc, etc)... if found returns true (not null) , ancestorcount==0 return this, othewise decrement ancestorcount before returning found child...
does make sense you? i'll edit post in 10 minutes put psuedocode (at least).
cheers. keith.
edit: provide sort-of code at-least.
this isn't compiled, let-alone tested... , therefore i'm not @ i've got condition correct... ben pointed out, might have assbackwards ;-) kind of thing typically have debug while right... think "i'm pretty close", , core idea there... i'll leave fine-tuning upto implementor... ;-)
public static node find(node node, string targetname, ref int ancenstorcount) { if ( node == null ) return null; if ( ancenstorcount == 0 ) // we've found right level return return node; if ( node.name == targetname ) return node; foreach ( node child in node.children ) { var found = find(child, targetname); if ( found != null ) { if ( ancenstorcount == 0 ) return found; --ancenstorcount; return node; // return non-null } } return null; }
... can see i'm going have implement node now, satisfy own curiosity correctness of algorith. sigh.
cheers. keith.
edit2:
well, works me...
using system; using system.collections.generic; using system.linq; using system.text; namespace tree { class node { private list<node> _kids = new list<node>(); public string name { get; set; } public list<node> children { { return _kids; } } public void add(node child) { _kids.add(child); } public override string tostring() { return name; } } class program { node _root; static void main(string[] args) { new program().run(); console.write("press key ..."); console.readkey(); } program() { _root = generatetree(); } static node generatetree() { // gen0 node root = new node() { name = "great-grandpa jimmy joe jim-bob john keith luke duke" }; // add gen1 gen0 root.add(new node() { name = "granduncle joe duke" }); node granddad = new node() { name = "granddad jimmy duke" }; root.add(granddad); // add gen2 gen1 granddad.add(new node() { name = "uncle jim" }); granddad.add(new node() { name = "uncle bob" }); node dad = new node() { name = "dad john" }; granddad.add(dad); // add gen3 gen2 dad.add(new node() { name = "brother luke" }); dad.add(new node() { name = "keith" }); return root; } void run() { console.writeline("my great-granddad is: " + find("keith", 3)); console.writeline("my granddad is: " + find("keith", 2)); console.writeline("my dad is: " + find("keith", 1)); console.writeline(); console.writeline("brother luke's dad is: " + find("brother luke", 1)); console.writeline("uncle bob's dad is: " + find("uncle bob", 1)); console.writeline("uncle jim's granddad is: " + find("uncle jim", 2)); console.writeline(); console.writeline("lunil's mom is: " + find("lunil", 1)); console.writeline(); } string find(string targetname, int anticedentlevel) { node n = find(_root, targetname, ref anticedentlevel); return n!=null ? n.tostring() : "#not_found#"; } private static node find(node node, string targetname, ref int ancenstorcount) { if ( node == null ) return null; if ( ancenstorcount == 0 ) // we've found right level return return node; if ( node.name == targetname ) return node; foreach ( node child in node.children ) { var found = find(child, targetname, ref ancenstorcount); if ( found != null ) { if ( ancenstorcount == 0 ) return found; --ancenstorcount; return node; // return non-null } } return null; } } }
output
great-granddad is: great-grandpa jimmy joe jim-bob john keith luke duke granddad is: granddad jimmy duke dad is: dad john brother luke's dad is: dad john uncle bob's dad is: granddad jimmy duke uncle jim's granddad is: great-grandpa jimmy joe jim-bob john keith luke duke lunil's mom is: #not_found# press key ...
... though in real world you'd "just" implement parent reference in each node, because that's simpler... , useful other things.
Comments
Post a Comment