我一直在努力解决这个问题大约整整一周,在这一点上,我想知道如果不深入C#语言就可以解决它,而我对C#还是相当陌生以及处理CSV文件并对其进行排序和组织,因此我对整个过程没有足够的经验。
我正在尝试按字母顺序对CSV文件进行排序,隐藏需要隐藏的项目,并根据其父项,子项和孙子元素使它们具有深度级别。
我已经成功使用了其中的一些,并编写了一些有效的代码,但是我不知道如何按字母顺序对它们进行排序,并根据它们所属的父级和子级为它们提供适当的深度层。
这是我一直试图组织的样机CSV:
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
我用分号分隔了项目,显示了需要显示的项目,但是我没有按照我的方式对它们进行排序。
排序应如下所示:
Company
About Us
Team
Mission
References
Client 1
Client 2
我试图通过获取斜杠的索引来对它们进行排序或按顺序显示它们,但是代码所再现的不是应该如何显示它,它看起来像这样:
Company
About Us
Mission
Team
Client 2
Client 1
References
在另一种尝试中,我将其父ID与ID递归匹配,控制台显示如下:
Company
About Us
Mission
Team
Client 2
Client 1
References
我曾尝试与一位朋友解决此问题,即使他也不知道如何解决此问题,因为此代码应在使用不同父ID的其他文件上工作。
最重要的是,我无法将它们索引到数组,因为只有索引0或索引基于它们的字母,或者如果我输入索引位置1会使控制台崩溃。
这是第一部分无法对它们进行排序的代码:
class Program
{
static void Main(string[] args)
{
StreamReader sr = new StreamReader(@"Navigation.csv");
string data = sr.ReadLine();
while (data != null)
{
string[] rows = data.Split(';');
int id;
int parentId;
bool ids = Int32.TryParse(rows[0], out id);
string name = rows[1];
bool pIds = Int32.TryParse(rows[2], out parentId);
string isHidden = rows[3];
string linkUrl = rows[4];
string[] splitted = linkUrl.Split('/');
if (isHidden == "False")
{
List<CsvParentChild> pIdCid = new List<CsvParentChild>()
{
new CsvParentChild(id, parentId, name, linkUrl)
};
}
data = sr.ReadLine();
}
}
}
class CsvParentChild
{
public int Id;
public int ParentId;
public string Name;
public string LinkUrl;
public List<CsvParentChild> Children = new List<CsvParentChild>();
public CsvParentChild(int id, int parentId, string name, string linkUrl)
{
Id = id;
ParentId = parentId;
Name = name;
LinkUrl = linkUrl;
string[] splitted = linkUrl.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
if (splitted.Length == 1)
{
Console.WriteLine($". { name }");
}
else if (splitted.Length == 2)
{
Console.WriteLine($".... { name }");
}
else if (splitted.Length == 3)
{
Console.WriteLine($"....... { name }");
}
}
}
这是第二部分:
class Program
{
static void Main(string[] args)
{
// Get the path for the file
const string filePath = @"../../Navigation.csv";
// Read the file
StreamReader sr = new StreamReader(File.OpenRead(filePath));
string data = sr.ReadLine();
while (data != null)
{
string[] rows = data.Split(';');
ListItems lis = new ListItems();
int id;
int parentId;
// Get the rows/columns from the Csv file
bool ids = Int32.TryParse(rows[0], out id);
string name = rows[1];
bool parentIds = Int32.TryParse(rows[2], out parentId);
string isHidden = rows[3];
string linkUrl = rows[4];
// Split the linkUrl so that we get the position of the
// elements based on their slash
string [] splitted = linkUrl.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
// If item.isHidden == "False"
// then display the all items whose state is set to false.
// If the item.isHidden == "True", then display the item
// whose state is set to true.
if (isHidden == "False")
{
// Set the items
ListItems.data = new List<ListItems>()
{
new ListItems() { Id = id, Name = name, ParentId = parentId },
};
// Make a new instance of ListItems()
ListItems listItems = new ListItems();
// Loop through the CSV data
for (var i = 0; i < data.Count(); i++)
{
if (splitted.Length == 1)
{
listItems.ListThroughItems(i, i);
}
else if (splitted.Length == 2)
{
listItems.ListThroughItems(i, i);
}
else
{
listItems.ListThroughItems(i, i);
}
}
}
// Break out of infinite loop
data = sr.ReadLine();
}
}
public class ListItems
{
public int Id { get; set; }
public string Name { get; set; }
public int ParentId { get; set; }
public static List<ListItems> data = null;
public List<ListItems> Children = new List<ListItems>();
// http://stackoverflow.com/a/36250045/7826856
public void ListThroughItems(int id, int level)
{
Id = id;
// Match the parent id with the id
List<ListItems> children = data
.Where(p => p.ParentId == id)
.ToList();
foreach (ListItems child in children)
{
string depth = new string('.', level * 4);
Console.WriteLine($".{ depth } { child.Name }");
ListThroughItems(child.Id, level + 1);
}
}
}
}
对于每个项目,您需要构造一种由ID组成的“排序数组”。排序数组由项的祖先的ID组成,按从最远到最远的顺序排列。对于“团队”,我们的排序数组为[1, 2, 4]
。
这是每个项目的排序数组:
[1]
[1, 2]
[1, 3]
[1, 2, 4]
[10, 5]
[10, 6]
[10, 7]
[10, 8]
[10]
一旦有了这些,就可以对项目进行分类。比较两个“排序数组”时,请在每个数组中按顺序从数字开始。如果它们不同,则根据第一个数字的值进行排序,然后完成。如果它们相同,请查看第二个数字。如果没有第二个数字,则按数组的长度排序,即,什么都没有。
应用此算法,我们得到:
[1]
[1, 2]
[1, 2, 4]
[1, 3]
[10]
[10, 5]
[10, 6]
[10, 7]
[10, 8]
之后,根据标记隐藏项目。我把它留给你,因为它是如此简单。深度很简单:这是排序数组的长度。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句