Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/firebase/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将平面对象列表转换为C#中的嵌套对象列表(递归?)_C#_Recursion_Nested_Data Conversion - Fatal编程技术网

将平面对象列表转换为C#中的嵌套对象列表(递归?)

将平面对象列表转换为C#中的嵌套对象列表(递归?),c#,recursion,nested,data-conversion,C#,Recursion,Nested,Data Conversion,我希望有人能帮我这个 假设我有一个基本的书签类: 公共类书签 { 公共int页索引{get;set;} 公共字符串路径{get;set;} } 以及书签的“平面”列表: List flatBookmarks=新列表() { 新FlatBookmark(){Path=“Category 1 | |第1页”,PageIndex=0}, 新FlatBookmark(){Path=“Category 1 | | |第1页| |附件1”,PageIndex=1}, 新FlatBookmark(){Pat

我希望有人能帮我这个

假设我有一个基本的书签类:

公共类书签
{
公共int页索引{get;set;}
公共字符串路径{get;set;}
}
以及书签的“平面”列表:

List flatBookmarks=新列表()
{
新FlatBookmark(){Path=“Category 1 | |第1页”,PageIndex=0},
新FlatBookmark(){Path=“Category 1 | | |第1页| |附件1”,PageIndex=1},
新FlatBookmark(){Path=“Category 1 | |第1页| |附件2”,PageIndex=2},
新FlatBookmark(){Path=“Category 1 | |第2页”,PageIndex=3},
new FlatBookmark(){Path=“Category 1 | |第2页”,PageIndex=4},//忽略(路径已存在)
new FlatBookmark(){Path=“Category 1 | |第2页”,PageIndex=5},//忽略(路径已存在)
新FlatBookmark(){Path=“Category 1 | |第3页”,PageIndex=6},
new FlatBookmark(){Path=”“,PageIndex=123},//应完全忽略空路径或空路径
new FlatBookmark(){Path=null,PageIndex=321},//应完全忽略空路径或null路径
新FlatBookmark(){Path=“Category 2 | |第1页”,PageIndex=7},
新FlatBookmark(){Path=“Category 2 | |第2页”,PageIndex=8},
new FlatBookmark(){Path=“Category 1 | | Page 1 | | | Attachment 1”,PageIndex=9},//创建一个新的“Category1”根,因为它由上一个根分隔
new FlatBookmark(){Path=“Category 1 | |第1页| |附件1”,PageIndex=10},//忽略(路径已存在)
新FlatBookmark(){Path=“Category 1 | |第1页| |附件2”,PageIndex=11},
};
现在我想用嵌套的书签填充一个新的
列表
,在路径的任何给定字符串上拆分,其中标题成为路径的最后一部分

公共类书签
{
公共int页索引{get;set;}
公共字符串标题{get;set;}
公共列表书签;//嵌套子项
}
像这样:

Category 1: PageIndex=0
    Page 1: PageIndex=0
        Attachment 1: PageIndex=1
        Attachment 2: PageIndex=2
    Page 2: PageIndex=3
    Page 3: PageIndex=6
Category 2: PageIndex=7
    Page 1: PageIndex=7
    Page 2: PageIndex=8
Category 1: PageIndex=9
    Page 1: PageIndex=9
        Attachment 1: PageIndex=9
        Attachment 2: PageIndex=11
我为它创建了一个单元测试:

//类别1
Assert.AreEqual(“类别1”,书签[0]。标题);
Assert.AreEqual(0,书签[0].PageIndex);
Assert.AreEqual(“第1页,书签[0]。书签[0]。标题);
Assert.AreEqual(0,书签[0]。书签[0]。页面索引);
Assert.AreEqual(“附件1”,书签[0]。书签[0]。书签[0]。标题);
Assert.AreEqual(1,书签[0]。书签[0]。书签[0]。页面索引);
Assert.AreEqual(“附件2”,书签[0]。书签[0]。书签[1]。标题);
Assert.AreEqual(2,书签[0]。书签[0]。书签[1]。页面索引);
Assert.AreEqual(“第2页,书签[0]。书签[1]。标题);
Assert.AreEqual(3,书签[0]。书签[1]。页面索引);
Assert.AreEqual(“第3页,书签[0]。书签[2]。标题);
Assert.AreEqual(6,书签[0]。书签[2]。页面索引);
//第2类
Assert.AreEqual(“类别2”,书签[1]。标题);
Assert.AreEqual(7,书签[1].PageIndex);
Assert.AreEqual(“第1页,书签[1]。书签[0]。标题);
Assert.AreEqual(7,书签[1]。书签[0]。页面索引);
Assert.AreEqual(“第2页,书签[1]。书签[1]。标题);
Assert.AreEqual(8,书签[1]。书签[1]。页面索引);
//第1类(未与第一类合并,因为中间有另一类)
Assert.AreEqual(“类别1”,书签[2]。标题);
Assert.AreEqual(9,书签[2].PageIndex);
Assert.AreEqual(“第1页,书签[2]。书签[0]。标题);
Assert.AreEqual(9,书签[2]。书签[0]。页面索引);
Assert.AreEqual(“附件1”,书签[2]。书签[0]。书签[0]。标题);
Assert.AreEqual(9,书签[2]。书签[0]。书签[0]。页面索引);
Assert.AreEqual(“附件2”,书签[2]。书签[0]。书签[1]。标题);
Assert.AreEqual(11,书签[2]。书签[0]。书签[1]。页面索引);
我被递归部分卡住了(我想…),我可以循环遍历每个
FlatBookmark
,并拆分路径(
string[]parts=bookmark.split(“/”)
),然后对于每个部分,我想以某种方式回顾一下它是否有父级,或者应该有父级,如果没有:创建它们

也许有人能告诉我如何创建这样一个方法的正确方向吗

它基本上不应该限制嵌套元素的数量

---更新---

  • 使用不同的分隔符更新了flatBookmark列表
  • 要求在任何给定字符串上分离路径
  • 删除了输出书签中“路径”的要求(标题已足够)
  • 额外要求:应保留书签的顺序;只有当同一级别上具有相同标题的多个书签之间没有其他标题时,才应将它们组合在一起
---解决方案---

这就是我提出的解决方案:

public List CreateNestedBookmarks(List flatBookmarks,字符串分隔符=“/”)
{
//创建一个“根”书签列表(发生在每个嵌套级别上,带有递归)
var bookmarks=新列表();
foreach(flatBookmarks中的var flatBookmark)
{
如果(!string.IsNullOrWhiteSpace(flatBookmark.Path))
{
//只使用标题
string title=flatBookmark.Path.Split(新字符串[]{separator},StringSplitOptions.None)[0];
bool exists=bookmarks.LastOrDefault()?.Title==Title;
//如果书签之前未添加且不为空/null,则将其添加到列表中
如果(!exists&&!string.IsNullOrWhiteSpace(title))
{
bookmarks.Add(新书签()
{
头衔,
PageIndex=flatBookmark.PageIndex
});
}
}
}
//获取每个“根”书签的嵌套书签
foreach(书签中的var书签)
{
bool-found=false;
List childBookmarks=新列表();
foreach(var)书签
public List<Bookmark> ParseFlatBookmarks (List<FlatBookmark> flatBookmarks)
{
    // define the list of local root bookmarks.

    // loop over the FLAT bookmarks

        // look only for the root bookmark in each path
        // (ex. in Path = "Category 1/Page 1" you will look for "Category 1")

        // then you check if found bookmark is already present in your root bookmarks list, if it is not than you create it and add it to the list.

    // loop over found root bookmarks

        // create a list of all the FLAT bookmarks that has current root bookmark as root
        // (ex. if you have "Category 1" as current root bookmark you will have a list containing "Category 1/Page 1", "Category 1/Page 1/Attachment 1", etc. and the last one will be "Category 1/Page 3".

        // to recursively navigate the FLAT bookmarks you will need to adjust their path.
        // To do that just remove root bookmark from path
        // (ex. if you currently have "Category 1" as root bookmark "Category 1/Page 1" as FLAT bookmark, you will have to set its path as "Page 1")

        // recursive call passing currently root bookmark's FLAT bookmark children as parameter
        // add found bookmarks to the currently root bookmark

    // return list of root bookmarks
}