F#父/子列表到Excel

时间:2011-10-04 13:50:46

标签: f#

我还是F#的新手所以希望我的问题不是太愚蠢。我正在创建一个Excel文件。我用C#做了很多Excel,所以这不是问题。我有一个父行列表,然后是子行列表。将它吐入Excel并跟踪Excel所属的行的最佳方法是什么。

假设我的列表rowHdr是一个Row类型列表,我有类似的东西:

let setCellText (x : int) (y : int) (text : string) = 
   let range = sprintf "%c%d" (char (x + int 'A')) (y+1)
   sheet.Range(range).Value(Missing.Value) <- text

type Row = 
    {   row_id:string
        parent_id:string
        text:string }

let printRowHdr (rowIdx:int) (colIdx:int) (rowToPrint:Row) rows = 
    setCellText colIdx rowIdx rowToPrint.text

List.iteri (fun i x -> printRowHdr (i+1) 0 x rows) <| rowHdr

我仍然无法考虑有时候最好的功能方法。在printRowHdr函数的某处,我需要遍历parent_id等于父行id的行的子行。我的麻烦在于知道它属于Excel中的哪一行。也许这是完全错误的方法,但我感谢任何建议。

感谢您的帮助,我衷心感激。

谢谢, 尼克

编辑添加:

Tomas - 感谢您的帮助。假设我有两个列表,一个是美国州,另一个是城市。城市列表还包含州缩写。我想循环通过州,然后获得每个州的城市。所以它在Excel中可能看起来像这样:

Alabama 
    Montgomery 
California 
    San Francisco 
Nevada 
    Las Vegas 
etc... 

考虑到这两个列表,我可以将它们以某种方式加入到一个列表中吗?

1 个答案:

答案 0 :(得分:1)

我不完全确定我是否理解你的问题 - 给出一个具体的例子,其中包含一些输入和你想要获得的Excel表格的截图将非常有用。

然而,使用 ID 来模拟父/子关系(如果这是你想要做的事情)的想法听起来不是最好的功能方法。我想你正试图代表这样的事情:

First  Row
       Foo  Bar
       Foo  Bar
Second Row
       More Stuff Here
            Some  Even  More  Neste  Stuff

这可以使用递归类型来表示,该递归类型包含当前行中的项列表,然后是子行列表(它们本身可以包含子行):

type Row = Row of list<string> * list<Row>

然后,您可以使用递归函数处理结构。值的示例(表示上述示例中的前三行)可以是:

Row( ["First"; "Row"],
     [ Row( ["Foo"; "Bar"], [] )
       Row( ["Foo"; "Bar"], [] ) ])

编辑:如果您有任意嵌套,上面的Row类型会很有用。如果您只有两个图层(州和城市),则可以使用列表列表。另一个列表包含州名以及包含该州所有城市的嵌套列表。

如果您从两个列表开始,那么您可以使用几个F#函数将输入转换为列表列表:

let states = [ ("WA", "Washington"); ("CA", "California") ]
let cities = [ ("WA", "Seattle"); ("WA", "Redmond"); ("CA", "San Francisco") ]

cities
// Group cities by the state
|> Seq.groupBy (fun (id, name) -> id)
|> Seq.map (fun (id, cities) ->
    // Find the state name for this group of cities
    let _, name = states |> Seq.find (fun (st, _) -> st = id)
    // Return state name and list of city names
    name, cities |> Seq.map snd)

然后,您可以递归迭代嵌套列表(在上面,它们实际上是序列,因此您可以使用List.ofSeq将它们转换为列表)并保留当前行和列的索引。