F # найти в списке записей записи с одинаковым идентификатором и сложить их значения - PullRequest
1 голос
/ 29 марта 2012

Я новичок в F #, у меня следующая отправная точка:

type aB = { ID: int; Slide: list<string * int> }

// examples of aB's
let aB1 = { ID = 1; Slide = [("-10%",-20); ("0%",0); ("10%",20)] }
let aB2 = { ID = 2; Slide = [("-10%",6); ("0%",0); ("10%",3)] }
let correctoraB2 = {ID = 2; Slide = [("-10%", -2); ("0%", 0); ("10%", -1)]  }

// Now we bunch the aB`s in a list together 
let bunchedABRaw = [aB1; aB2; correctoraB2]

Этот список теперь может стать довольно длинным, в этом списке мне нужно сначала идентифицировать все АБ с одинаковыми идентификаторами, затем яЯ хочу получить свои слайды, чтобы получился новый список

let bunchedABReduced = [aB1; aB2New], где

aB2New = { ID = 2; Slide = [("-10%",4); ("0%",0); ("10%",2)] }

Я читаю библиотеку F # на MSDN, но такПока я не знаю, как решить проблему, был бы очень рад предложению кода.

Большое спасибо Мартин

Ответы [ 2 ]

2 голосов
/ 29 марта 2012

ОК, пробираюсь через это, когда у меня есть минутка.

Вот первая часть, где вы можете объединить слайды двух АБ:

// this function can merge two slides
let mergeSlides l1 l2 = 
    List.zip l1 l2
    |> List.map (fun ((a1, b1), (a2,b2)) -> (a1, b1+b2))

// see what it does
mergeSlides aB2.Slide correctoraB2.Slide

Этот бит группирует все АБ с одинаковым Id:

let grp = bunchedABRaw
|> Seq.groupBy (fun a -> a.ID)

ИТеперь мы можем использовать mergeSlides в качестве функции свертывания, которую мы используем сворачивание для каждой последовательности Ab с тем же Id, чтобы сделать netB aB.

Итак, вот и все:

let mergeSlides l1 l2 = 
    List.zip l1 l2
    |> List.map (fun ((a1, b1), (a2,b2)) -> (a1, b1+b2))

let net =
    bunchedABRaw
    |> Seq.groupBy (fun a -> a.ID)
    |> Seq.map (fun (i, s) -> (i, s |> Seq.map (fun a -> a.Slide))) // strip away the slides
    |> Seq.map (fun (i, s) -> (i, List.ofSeq s)) // turn seq<slide> into list<slide>
    |> Seq.map (fun (i, l) -> (i, List.fold mergeSlides l.Head l.Tail)) // so we can use HEad and Tail
    |> Seq.map (fun (i, l) -> {ID=i;Slide=l}) // and Project into aB
    |> List.ofSeq // and then List

Наслаждайтесь!

0 голосов
/ 29 марта 2012

Попробуйте:

Настройте словарь, в котором ключами будут идентификаторы, с которыми вы столкнетесь, а значения будут иметь тип netB aB для этого идентификатора.

Затем выполните складывание* в списке, используя словарь в качестве вашего состояния и функцию, которую вы сверните по списку, накапливайте элементы в словаре по идентификатору («цепляя» их по ходу работы).

После этого вы можете поместить всезначения словаря в возвращаемый список.

Если вы не можете «чистить» их по ходу дела, вы можете сохранить список элементов в виде значений вместо одного значения «нетто», а затем выполнить взаимозачет послесгиб заканчивается.

* сгиб http://msdn.microsoft.com/en-us/library/ee353894.aspx

РЕДАКТИРОВАТЬ: сделал некоторые вещи яснее

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