Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.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
Recursion F#如何从嵌套集创建树?_Recursion_F#_Tree_Nested Sets - Fatal编程技术网

Recursion F#如何从嵌套集创建树?

Recursion F#如何从嵌套集创建树?,recursion,f#,tree,nested-sets,Recursion,F#,Tree,Nested Sets,我有数据库中的嵌套集数据,需要将其转换为树数据结构: 类型项={ Id:int 左:int 右:int 级别:int } 类型项目=项目列表 类型树={Parent:Item;Childrens:Tree list} 我失败的尝试: 获取根项的子项并创建树的根 为步骤1中的每个子级搜索子级,构建新树 重复步骤2,直到将所有项目(嵌套集)转换为树 let谓词pc=(c.Level=p.Level+1)&&(c.Left>p.Left)&(c.RightinitLeaf x) 让getChildr

我有数据库中的嵌套集数据,需要将其转换为树数据结构:

类型项={
Id:int
左:int
右:int
级别:int
}
类型项目=项目列表
类型树={Parent:Item;Childrens:Tree list}
我失败的尝试:

  • 获取根项的子项并创建树的根
  • 为步骤1中的每个子级搜索子级,构建新树
  • 重复步骤2,直到将所有项目(嵌套集)转换为树
  • let谓词pc=(c.Level=p.Level+1)&&(c.Left>p.Left)&(c.RightinitLeaf x)
    让getChildrens parent=List.filter(乐趣x->谓词父x)
    让生成(initList:itemlist)=
    让sortedList=initList |>List.sortBy(乐趣x->x.Left)
    让getChildrens2父项=
    let items=sortedList |>getChildrens父项
    如果不是(List.isEmpty items),则items |>initLeafs else[]
    让root=initLeaf sortedList.Head
    让rec循环(树:树)=
    让孩子们=
    火柴树。孩子们用火柴
    | [] -> 
    getChildrens2树。父
    |x->
    x |>List.collect(乐趣y->循环y)
    循环{tree with Childrens=Childrens}
    环根
    让res=生成项
    
    以下是我的尝试。这一例子取自。 我将
    Item.Id
    的类型更改为
    string
    ,以提高输出的可读性, 但该方法仍然适用

    []
    类型项={Id:string;Left:int;Right:int;Level:int}
    类型树={节点:项;子节点:树列表}
    让lst:项目列表=[
    {Id=“衣服”;左=1;右=22;级别=0}
    {Id=“男式”左=2;右=9;级别=1}
    {Id=“女子”左=10;右=21;级别=1}
    {Id=“suites”;左=3;右=8;级别=2}
    {Id=“Slacks”;左=4;右=5;级别=3}
    {Id=“夹克”;左=6;右=7;级别=3}
    {Id=“连衣裙”;左=11;右=16;级别=2}
    {Id=“裙子”;左=17;右=18;标高=2}
    {Id=“衬衫”;左=19;右=20;级别=2}
    {Id=“晚礼服”;左=12;右=13;层=3}
    {Id=“太阳裙”;左=14;右=15;级别=3}
    ]
    让sorted=lst |>List.sortBy(乐趣x->x.Left)
    让rootItem::未指定=已排序
    设isParentOf p c=(c.Level=p.Level+1)和&(c.Left>p.Left)和&(c.Right
    输出(截断):

    编辑:这是我能想到的最短尾部递归版本

    let buildTree1(根:项):树=
    放手(待定:项目列表)(m:Map):Map=
    匹配
    |[]->m
    |x::xs->
    让子项=List.filter(isParentOf x)未指定
    如果List.i是空孩子,那么
    让mUpd=Map.addx{Node=x;Children=[]}m
    go xs mUpd
    其他的
    让pendingChildren=List.filter(乐趣y->not
    让子树=List.map(funx->m[x])子树
    设mUpd=Map.addx{Node=x;Children=subtrees}m
    go xs mUpd
    |ps->go(ps@(x::xs))m
    转到[root]Map.empty |>Map.find root
    let tree=buildTree1根项目
    
    也许可以用连续传球的方式来改进

    val tree : Tree =
      { Node = 'Clothing'(L:1 R:22)
        Children =
                  [{ Node = 'Men's'(L:2 R:9)
                     Children =
                               [{ Node = 'Suits'(L:3 R:8)
                                  Children =
                                            [{ Node = 'Jackets'(L:6 R:7)
                                               Children = [] };
                                             { Node = 'Slacks'(L:4 R:5)
                                               Children = [] }] }] };
                   { Node = 'Women's'(L:10 R:21)
    ...