读取csv文件并返回缩进菜单c#




我必须使用.csv文件中的以下数据创建一个缩进的导航菜单:

ID;MenuName;ParentID;isHidden;链接URL
1;公司空;错误/公司
2;关于我们;1.错误/公司/关于我们
3;使命1.错误/公司/使命
4;团队2.错误/公司/关于我们/团队
5;客户2;10;错误/引用/客户端2
6;客户1;10;错误/引用/客户端1
7;客户4;10;对/引用/客户端4
8;客户5;10;对/参考资料/客户5
10;参考文献;空;错误/参考

使用这些数据,我必须开发一个应用程序,该应用程序将解析文件并在控制台中显示内容,如下所示:

公司
。。。。关于我们
。。。。。。。团队
。。。。使命
。引用
。。。。客户端1
。。。。客户端2

菜单项应缩进(取决于父项(,不应显示隐藏项(isHidden=true(,并且应按字母顺序排列。到目前为止,我尝试过:

using (StreamReader sr = new StreamReader(@"file.csv"))
{
// Read the stream to a string, and write the string to the console.
string [] lines = sr.ReadToEnd().Split(/*';', */'n');                
for (int i = 1; i < lines.Length; i++)
{                    
Console.WriteLine($"String no {i} is : {lines[i-1]}");
}                
}

有了这个,我得到了台词,但我被卡住了。我是编码方面的新手,所以任何帮助都将不胜感激:(

这里有一些代码应该可以帮助你摆脱困境

工作样品:

https://dotnetfiddle.net/L37Gjr

它首先将数据解析为一个单独的对象。然后,它被用来构建一个m元树,或者连接节点的层次结构。(一个节点引用了0个或多个子节点(。

https://en.wikipedia.org/wiki/M-ary_tree

然后使用树遍历(如果您需要了解更多信息,请使用谷歌(来插入和打印输出,但是仍然存在问题。它现在使用级别顺序遍历来打印,但是会出现一个错误:

Found root:1 - Company
Found root:10 - References
-------------------
1 - Company
2 - About Us
3 - Mission
4 - Team
10 - References
6 - Client 1
5 - Client 2

正如您所看到的,它在错误的级别上打印4 - Team。我会让你来解决它(因为我没有时间了(,如果没有,我希望我给了你很多想法,让你自己去研究。

// sample for https://stackoverflow.com/questions/61395486/read-csv-file-and-return-indented-menu-c-sharp by sommmen
using System;
using System.Collections;
using System.Linq;
using System.Collections.Generic;
public class Program
{
public class Node<T>
{
public T Data {get;set;}    
public List<Node<T>> Children { get; set;}
public Node()
{
Children = new List<Node<T>>();
}
// Tree traversal in level order
public List<Node<T>> LevelOrder()
{
List<Node<T>> list = new List<Node<T>>();
Queue<Node<T>> queue = new Queue<Node<T>>();
queue.Enqueue(this);
while(queue.Count != 0)
{               
Node<T> temp = queue.Dequeue();
foreach (Node<T> child in temp.Children)
queue.Enqueue(child);
list.Add(temp);
}
return list;
}
public List<Node<T>> PreOrder()
{
List<Node<T>> list = new List<Node<T>>();
list.Add(this);
foreach (Node<T> child in Children)
list.AddRange(child.PreOrder());
return list;
}
public List<Node<T>> PostOrder()
{
List<Node<T>> list = new List<Node<T>>();
foreach (Node<T> child in Children)
list.AddRange(child.PreOrder());
list.Add(this);
return list;
}

}
public class Entity
{
public int id   {get;set;}
public string menuName {get;set;}
public int? parentID {get;set;}
public bool isHidden {get;set;}
public string linkURL  {get;set;}
}
public static void Main()
{
var data = @"ID;MenuName;ParentID;isHidden;LinkURL
1;Company;NULL;False;/company
2;About Us;1;False;/company/aboutus
3;Mission;1;False;/company/mission
4;Team;2;False;/company/aboutus/team
5;Client 2;10;False;/references/client2
6;Client 1;10;False;/references/client1
7;Client 4;10;True;/references/client4
8;Client 5;10;True;/references/client5
10;References;NULL;False;/references";
var lines = data.Split('n');
var rootNodes = new List<Node<Entity>>();
var childItems = new List<Entity>();
// Parse the data to entities
// Items without a parent are used as rootnodes to build a tree
foreach(var row in lines.Skip(1))
{           
var columns = row.Split(';');
var id       = Convert.ToInt32(columns[0]);
var menuName = columns[1];
var parentID = ToNullableInt(columns[2]);
var isHidden = Convert.ToBoolean(columns[3]);
var linkURL  = columns[4];
var entity = new Entity()
{
id = id,
menuName = menuName,
parentID = parentID,
isHidden = isHidden,
linkURL = linkURL
};
if(parentID == null)
{
Console.WriteLine("Found root:" + entity.id + " - " + entity.menuName);
rootNodes.Add(new Node<Entity>()
{
Data = entity
});
}
else
{
childItems.Add(entity); 
}
}
// Add the childElements to their appropriate rootnode
foreach(var rootNode in rootNodes)
{
foreach(var childItem in childItems.OrderBy(a=>a.parentID).ThenBy(b=>b.menuName))
{
var newNode = new Node<Entity>()
{
Data = childItem
};
Insert(rootNode, newNode);
}
}
Console.WriteLine("-------------------");
foreach(var rootNode in rootNodes)
{
var indent = 0;
var previous = rootNode;
foreach(var node in rootNode.LevelOrder())
{
if(node.Data.isHidden) continue;
if(previous.Data.parentID != node.Data.parentID)
indent++;
for(var i = 0; i < indent; i++)
Console.Write("t");
Console.WriteLine(node.Data.id + " - " + node.Data.menuName);
previous = node;
}
}
}
public static void Insert(Node<Entity> rootNode, Node<Entity> targetNode)
{
foreach(var current in rootNode.LevelOrder())
{
if(current.Data.id == targetNode.Data.parentID)
{
current.Children.Add(targetNode);   
return;
}
}
}
public static int? ToNullableInt(string s)
{
int i;
if (int.TryParse(s, out i)) return i;
return null;
}
}

最新更新