我设法在这里做了一大碗意大利面,无法找到出路。我试图将一个类型插入树中,然后重新排序树后的位置。
以下是我的类型:
type Government = {
Id : Id;
Name : string;
Abbreviation : string;
ParentId : string option;
}
type GovernmentStructure<'gov> =
| Root of Government : 'gov * SubGov : GovernmentStructure<'gov> list
| Node of Government : 'gov * SubGov : GovernmentStructure<'gov> list
| Leaf of Government : 'gov
这里是意大利面条lol。它没有用,但它显示了我被卷入的头脑风暴。
let insertGovernment (posGov: Government) (newGov : Government) (parentId : string)
(currentStructure : GovernmentStructure<Government> list) =
let rec reorderStructure (govPos : Government) (newGov : Government)
(currentStructure : GovernmentStructure<Government>) =
match currentStructure with
| Root(gov', subGov) when gov' = govPos ->
let rec updateSubGov parentId (movGov: Government)
(uSubGov : GovernmentStructure<Government> list) =
[
Node({
Government.Id = movGov.Id;
Name = movGov.Name;
Abbreviation = movGov.Abbreviation;
ParentId = Some(parentId)
},[
for x in uSubGov do
match x with
| Node(g, s) -> yield! (updateSubGov movGov.Id g s)
| Leaf(g) -> yield x
])
]
Root(newGov, (updateSubGov newGov.Id gov' subGov))
| node ->
let rec updateStructure parentId (insGov : Government)
(node : GovernmentStructure<Government> list) =
match node with
| Root(gov', subGov) ->
Root(gov', [
for (x) in subGov do
match x with
| Node(g,s) when g = govPos ->
yield Node(insGov, updateStructure g.Id s )
| Node(g,s) -> yield Node(g, updateStructure g.Id s)
])
| Node(gov', subGov) when gov' = govPos ->
[
Node({
Government.Id = insGov.Id;
Name = insGov.Name;
Abbreviation = insGov.Abbreviation;
ParentId = Some(parentId)
},[
for x in uSubGov do
match x with
| Node(g,s) -> yield Node(g, updateStructure movGov.Id g s)
])
]
| Leaf(g) ->
[
Node(newGov, [Leaf({
g with ParentId = newGov.Id
})])
]
node |> (fun x ->
match x with
| Root(g,s) -> Node(g,(updateStructure g.Id g s))
| Node(g,s) -> Node(g,(updateStructure g.Id g s)))
帮助!!!我淹死在酱汁里,哈哈。
答案 0 :(得分:0)
这是我能够提出的解决方案。我不怀疑存在更有效的答案。
let insertGovernment (posGov: Government) (newGov : Government)
(currentStructure : GovernmentStructure<Government>) =
let updateStructure (govPos : Government) (newGov : Government)
(currentStructure : GovernmentStructure<Government>) =
// iterate over the nodes to find position and insert. parentId is useless, will fix later
let rec findPosAndInsertInto parentId (startStructure : GovernmentStructure<Government>) =
match startStructure with
| Node (g, sg) when g = govPos ->
Node(g, [
yield Node(newGov, [])
yield! sg
])
| Node (g, sg) ->
Node (g, [
for x in sg do
yield findPosAndInsertInto g.Id x
])
| Leaf(g) when g = govPos ->
Node (g, [Leaf(newGov)])
// better logic needed, should not hit this
| node -> node
match currentStructure with
// Insert if position is at root
| Root(gov', subGov) when gov' = govPos ->
Root(gov', [
yield Node(newGov, [])
yield! subGov
])
// Insert if position is at node or leaf
| node ->
match node with
| Root (gov', subGov) ->
Root(gov', [
for x in subGov do
yield findPosAndInsertInto gov'.Id x
])
// better logic needed, shouldn't hit this level
| node -> node
updateStructure posGov newGov currentStructure