F # родительские / дочерние списки в Excel - PullRequest
2 голосов
/ 04 октября 2011

Я все еще новичок в 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 Ответ

1 голос
/ 04 октября 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...