开发者

F# parent/child lists to Excel

开发者 https://www.devze.com 2023-04-10 07:15 出处:网络
I\'m still new to F# so hopefully my question isn\'t too dumb. I\'m creating an Excel file. I\'ve done a lot of Excel with C# so that isn\'t a problem. I have a list of parent rows and then a list of

I'm still new to F# so hopefully my question isn't too dumb. I'm creating an Excel file. I've done a lot of Excel with C# so that isn't a problem. I have a list of parent rows and then a list of child rows. What's the best way to spit that into Excel and keep track of the row in Excel that it belongs in.

Assuming my list rowHdr is a list of Row types, I have something like this:

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

I still have trouble thinking about what the best functional approach is at times. Somewhere in the printRowHdr function I need to iterate through the child rows for the rows where the parent_id is equal to parent row id. My trouble is knowing what row in Excel it belongs in. Maybe this is totally the wrong approach, but I appreciate any suggestions.

Thanks for any help, I sincerely appreciate it.

Thanks, Nick

Edited to add:

Tomas - Thanks for the help. Let's say I have two lists, one with US states and ano开发者_如何学Pythonther with cities. The cities list also contains the state abbreviation. I would want to loop through the states and then get the cities for each state. So it might look something like this in Excel:

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

Given those two lists could I join them somehow into one list?


I'm not entirely sure if I understand your question - giving a concrete example with some inputs and a screenshot of the Excel sheet that you're trying to get would be quite useful.

However, the idea of using ID to model parent/child relationship (if that's what you're trying to do) does not sound like the best functional approach. I imagine you're trying to represent something like this:

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

This can be represented using a recursive type that contains the list of items in the current row and then a list of children rows (that themselves can contain children rows):

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

You can then process the structure using recursive function. An example of a value (representing first three lines from the example above) may be:

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

EDIT: The Row type above would be useful if you had arbitrary nesting. If you have just two layers (states and cities), then you can use list of lists. The other list containing state name together with a nested list that contains all cities in that state.

If you start with two lists, then you can use a couple of F# functions to turn the input into a list of lists:

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)

Then you can recursively iterate over the nested lists (in the above, they are actually sequences, so you can turn them to lists using List.ofSeq) and keep an index of the current row and column.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号