如何在F#中构建适当的数据结构?

时间:2016-10-11 01:45:56

标签: f#

我正在尝试构建数据结构,但我不确定如何完成它。我也不确定我是否有适合这种情况的模型。我想采用一个包含主键和外键的列表来构建此结构。数据由基于其排名的彼此相关的内容组成。例如:

[{Id = 1; Name = "United States"; Short = "USA"; ParentId = null}
 {Id = 2; Name = "President"; Short = "Pres"; ParentId = 1}
 {Id = 3; Name = "Senate"; Short = "Sen"; ParentId = 2}
 {Id = 4; Name = "House"; Short = "Hou"; ParentId = 2}
 {Id = 5; Name = "State"; Short = "Sta"; ParentId = null}
 {Id = 6; Name = "Governor"; Short = "Gov"; ParentId = 5}
 {Id = 7; Name = "City"; Short = "Cit"; ParentId = null}
 {Id = 8; Name = "Mayor"; Short = "May"; ParentId = 7}]

因此,基于上面的列表,我应该能够基于4个创建的列表或序列创​​建某种结构。 ID 1应包含ID 2. ID 2应包含3& 4. ID 5应包含6,ID 7应包含8。

我的模特:

// Not sure this record is right for the job. Maybe something else like a tree 
type Government = {
    Id : Id;
    Name : string;
    Abrreviation : string;
    Parent : Government option;
    Child : Government list option
}

let Select_AllGovStructures () =

    let govList = Select.Select_Government.Create(Admin.connectionString).Execute() |> Seq.toList

    let createStructure (govList : Select.Select_Government.Record list) =

        let parentList =

            govList
            |> List.choose (fun x -> 
                                match x.ParentId.IsNone with
                                | true -> Some x
                                | false -> None)

        let rec childList (currentList : Select.Select_Government.Record list) 
            (prevParentList : Select.Select_Government.Record list)
            (acc : Government list) =

            match (currentList, prevParentList, acc) with
            | [],_,acc -> acc
            | (cl, [], []) when  not cl.IsEmpty ->

                let newCurrentList =
                    currentList
                    |> List.where (fun x -> not (parentList
                                                   |> List.contains x))

                childList newCurrentList parentList
                    (parentList
                    |> List.map (fun x -> {
                                            Government.Id = x.Id;
                                            Name = x.Name;
                                            Abbreviation = x.Abbreviation;
                                            Parent = None;
                                            Child = childList newCurrentList parentList List.empty<Government>
                                        }))
            | (cl, ppL, acc)  -> 

                let parentList =

                    cl
                    |> List.choose (fun x -> 
                                        let parent =
                                            ppL |> List.where (fun p -> p.Id = x.ParentId.Value)
                                        match parent.IsEmpty with
                                        | true -> None
                                        | false -> Some x)
                let newCurrentList =
                    cl
                    |> List.where (fun x -> not (parentList
                                                    |> List.contains x))

                childList cl ppL 
                    (parentList
                    |> List.map (fun x -> {
                                            Government.Id = x.Id;
                                            Name = x.Name;
                                            Abbreviation = x.Abbreviation;
                                            Parent = // Lost! Help!!
                                            Child = // Lost! Help!!
                                        }))

        childList govList List.empty<Select.Select_Government.Record> List.empty<Government>   

    createStructure govList   

我是F#的新手并且是我自己学习的,所以我确信我可能过于复杂化了。我已经读到树木在这种情况下可能有用,也可以折叠或减少,但我无法完全解决问题。任何建议或帮助表示赞赏。

0 个答案:

没有答案