F # родительские / дочерние списки в Excel

#f#

#f#

Вопрос:

Я все еще новичок в F #, так что, надеюсь, мой вопрос не слишком глуп. Я создаю файл Excel. Я много работал с Excel на C #, так что это не проблема. У меня есть список родительских строк, а затем список дочерних строк. Каков наилучший способ перенести это в Excel и отслеживать строку в Excel, к которой она принадлежит.

Предполагая, что мой список rowHdr представляет собой список типов строк, у меня есть что-то вроде этого:

 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 равен идентификатору родительской строки. Моя проблема в том, чтобы знать, к какой строке в Excel она принадлежит. Возможно, это совершенно неправильный подход, но я ценю любые предложения.

Спасибо за любую помощь, я искренне ценю это.

Спасибо, Ник

Отредактировано для добавления:

Томас — Спасибо за помощь. Допустим, у меня есть два списка: один со штатами США, а другой с городами. Список городов также содержит сокращение штата. Я бы хотел перебрать штаты, а затем получить города для каждого штата. Так что в Excel это может выглядеть примерно так:

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

Учитывая эти два списка, могу ли я как-то объединить их в один список?

Ответ №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 ) и сохранить индекс текущей строки и столбца.

Комментарии:

1. Томас — Спасибо за помощь. Я отредактировал свой первоначальный вопрос с помощью примера.

2. @nickfinity Пример был очень полезен — я добавил несколько вещей к своему ответу.

3. Большое спасибо. У меня никогда не должно быть более двух уровней. Большое вам спасибо за вашу помощь.