0

我想知道这是否可能像问题所暗示的那样。我的问题是我似乎无法掌握如何处理给定输入值可以有多个孩子的事实。通过使用可变的 SortedSet 变量可以轻松解决该问题,如下所示。但我真的很想知道这是否是一个可以通过纯递归和创建新的非静音列表或类似列表来解决的问题。我希望我的问题很清楚。我担心我不知道这是不可能的简单结论。正如您在下面看到的,if(true) 将返回一个列表,但 else 将返回一个列表列表。所以下面的代码不处于工作状态。

let someSet = new System.Collections.Generic.SortedSet<string>()
let rec children(value:string,listSoFar) =
    printfn "ID: %A" value 
    someSet.Add(value) works fine of course.
    let newList = List.append listSoFar [value]
    if(not (hasChildren(value))) then 
        newList
    else
        let tmpCollection = database.GetCollection<Collection>("Collection")
        let tmpQuery = Query.EQ("Field",BsonValue.Create(value))
        let tmpRes = tmpCollection.Find(tmpQuery)
        [ for child in tmpRes do
            yield children(child.Value,newList) ]


let resultList = children("aParentStartValue",[]) 
//Or do i need to use someSet values?
4

1 回答 1

3

除非树嵌套非常深(在这种情况下,这将是低效的),您可以将代码编写为递归 F# 序列表达式,该表达式使用yieldyield!

let rec children (value:string) = seq {
    // Produce the current value as the next element of the sequence
    yield value
    if hasChildren value then 
      // If it has children, then get all the children
      let tmpCollection = database.GetCollection<Collection>("Collection")
      let tmpQuery = Query.EQ("Field",BsonValue.Create(value))
      let tmpRes = tmpCollection.Find(tmpQuery)
      // For each child, generate all its sub-children recursively
      // and return all such elements as part of this sequence using 'yield!'
      for child in tmpRes do
        yield! children child.Value }

// Using 'List.ofSeq' to fully evaluate the lazy sequence
let resultList = List.ofSeq (children "aParentStartValue")

如果树的嵌套更深,那么情况会更困难一些。在遍历所有子节点时,您需要将到目前为止收集的列表传递给第一个子节点,获取结果,然后将结果列表传递给下一个子节点(使用类似的东西List.fold)。但以上内容很干净,在大多数情况下应该可以工作。

于 2013-11-04T16:24:21.043 回答