当前位置: 首页 > 编程语言 > C#

C#生成层次结构的算法分享

时间:2023-04-10 19:37:12 C#

C#生成层次结构的算法我有一个文本文件,看起来是这样的:{Id=1,ParentId=0,Position=0,Title="root"}{id=2,ParentId=1,Position=0,Title="child1"}{Id=3,ParentId=1,Position=1,Title="child2"}{id=4,ParentId=1,Position=2,Title="child3"}{Id=5,ParentId=4,Position=0,Title="grandchild1"}我正在寻找一个从创建对象层次结构开始的通用C#算法。如果您愿意,可以使用“hierarchy”函数将此数据转换为对象层次结构。有任何想法吗?编辑我已将文件解析为.NET对象:classNode{publicintId{get;}publicintParentId{得到;}publicintPosition{得到;}公共字符串标题{得到;现在我需要将对象实际排列到对象图中。非常感谢Jon和mquander——你们给了我足够的信息来帮助我以正确、通用的方式解决这个问题。这是我的解决方案,一种将对象转换为分层形式的通用扩展方法:varchildrenFetcher=default(Func>>);childrenFetcher=parentId=>families[parentId].OrderBy(orderingKeySelector).Select(x=>newNode(x,childrenFetcher(keySelector(x))));返回childrenFetcher(topMostKey);}使用这个小节点类:publicclassNode{publicTValue{get;私有集;}publicIList>Children{get;私有集;}publicNode(Tvalue,IEnumerable>children){this.Value=value;this.Children=newList>(children);它的通用性足以解决各种问题,包括我的文本文件问题。漂亮的!****更新****:以下是您可以如何使用它://给定一些示例数据:varitems=new[]{newFoo(){Id=1,ParentId=-1,//表示没有父级Position=0},newFoo(){Id=2,ParentId=1,Position=0},newFoo(){Id=3,ParentId=1,Position=1}};//把它变成一个层次结构!//我们将返回一个包含根节点的节点列表。//每个节点都有一个子节点列表。var层次结构=项目。Hierarchize(-1,//“根级别”键。我们使用-1表示根级别。f=>f.Id,//对象的ID属性f=>f.ParentId,//The对象上指向其父对象的属性f=>f.Position,//对象上指定其父对象内顺序的属性);嗯……不太明白这是怎么回事。2和5怎么会有parent=1,position=0?5是否有父母2、3或4?好吧,这个新版本通过所有节点三次:它没有很好的封装、很好的错误检查等——但它有效。使用系统;使用System.Collections.Generic;使用System.IO;publicclassNode{privatestaticreadonlychar[]Braces="{}".ToCharArray();privatestaticreadonlychar[]StringTrim=""".ToCharArray();publicNodeParent{get;set;}publicintParentId{get;privateset;}publicintId{get;privateset;}publicstringTitle{get;私有集;}publicintPosition{get;privateset;}privatereadonlyListchildren=newList();publicListChildren{get{returnchildren;}}publicstaticNodeFromLine(stringline){Nodenode=newNode();line=line.Trim(Braces);string[]bits=line.Split(',');foreach(stringbitinbits){string[]keyValue=bit.Split('=');字符串键=keyValue[0].Trim();字符串值=keyValue[1].Trim();switch(key){case"Id":node.Id=int.Parse(value);break;case"ParentId":node.ParentId=int.Parse(value);break;case"Position":node.Position=int.Parse(value);break;case"Title":node.Title=value.Trim(StringTrim);休息;默认值:抛出新的ArgumentException(“错误行:”+行);}}返回节点;}publicvoidDump(){intdepth=0;节点节点=这个;while(node.Parent!=null){depth++;node=node.Parent;}Console.WriteLine(newstring('',depth*2)+Title);foreach(子节点中的子节点){child.Dump();}}}classTest{staticvoidMain(string[]args){vardictionary=newDictionary();使用(TextReaderreader=File.OpenText("test.txt")){字符串行;while((line=reader.ReadLine())!=null){Nodenode=Node.FromLine(line);字典[node.Id]=节点;}}foreach(Nodenodeindictionary.Values){if(node.ParentId!=0){node.Parent=dictionary[node.ParentId];node.Parent.Children.Add(节点);}}foreach(字典中的节点节点。值){node.Children.Sort((n1,n2)=>n1.Position.CompareTo(n2.Position));}节点根=字典[1];根.转储();}}示例文档:{Id=5,ParentId=4,Position=0,Title="grandchild1"}{Id=2,ParentId=1,Position=0,Title="child1"}{Id=4,ParentId=1,Position=2,Title="child3"}{Id=3,ParentId=1,Position=1,Title="child2"}{id=1,ParentId=0,Position=0,Title="root"}输出:rootchild1child2child3grandchild1解析文件后,您可以关注此博客,了解如何使用LINQ将对象组装到层次结构中。我假设您的示例错误地为对象#5提供了错误的父ID。这应该涵盖它。注意事项:假设“最顶层”节点的父ID始终为零。任何未从最顶层节点下降的节点都将被忽略。在重复ID的情况下,行为会很奇怪。公共类FlatObj{publicintId;公共intParentId;公共诠释职位;公共字符串标题;}publicclassNode{publicintID;公共字符串标题;公共IList儿童;publicNode(FlatObjectbaseObject,IListchildren){this.ID=baseObject.Id;this.Title=baseObject.Title;this.Children=孩子们;}}publicstaticNodeCreateHierarchy(IEnumerableobjects){varfamilies=objects.ToLookup(x=>x.ParentId);vartopmost=families[0].Single();功能>孩子=空;Children=(parentID)=>families[parentID].OrderBy(x=>x.Position).Select(x=>newNode(x,Children(x.Id))).ToList();returnnewNode(topmost,Children(topmost.Id));}publicstaticvoidTest(){Listobjects=newList{newFlatObj{Id=1,ParentId=0,Position=0,Title="root"},newFlatObj{Id=2,ParentId=1,Position=0,Title="child1"},newFlatObj{Id=3,ParentId=1,Position=1,Title="child2"},newFlatObj{Id=4,ParentId=1,Position=2,Title="child3"},newFlatObj{Id=5,ParentId=2,Position=0,Title="grandchild"}};变种节点=CreateHierarchy(对象);}classNode{publicintId{获取;设置;}publicintParentId{获取;设置;}publicintPosition{获取;设置;}publicstringTitle{get;set;}publicIEnumerableChildren{get;放;}publicoverridestringToString(){returnToString(0);}publicstringToString(intdepth){return"n"+newstring('',depth*2)+Title+(Children.Count()==0?"":string.Join("",Children.Select(node=>node.ToString(depth+1)).ToArray());}}classProgram{staticvoidMain(string[]args){vardata=new[]{newNode{Id=1,ParentId=0,Position=0,Title="root"},newNode{Id=2,ParentId=1,Position=0,Title="child1"},newNode{Id=3,ParentId=1,Position=1,Title="child2"},newNode{Id=4,ParentId=1,Position=2,Title="child3"},newNode{Id=5,ParentId=3,Position=0,Title="孙子1"}};函数转换=空;transform=node=>newNode{Title=node.Title,Id=node.Id,ParentId=node.ParentId,Position=node.Position,Children=(fromchildindatawherechild.ParentId==node.Idorderby孩子.Positionselecttransform(child))};Console.WriteLine(变换(数据[0]));}}结果:rootchild1child2grandchild1child3你确定最后一行的ParentID是1吗?标题是孙子,但如果我没看错的话,那将是一个“根”孩子这是@baran要求的示例:以上就是C#学习教程:C#生成层次结构的算法共享,如果有用的话给大家,需要了解更多C#学习教程,希望大家多多关注——varlHierarchicalMenuItems=lMenuItemsFromDB.Hierarchize(0,aItem=>aItem.Id,aItem=>aItem.ParentId,aItem=>aItem.位置);本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: