2013-04-02 3 views
7

У меня есть «сжатый» поток значения, к которому присоединен число вхождение этого значения, например:Повторяющиеся последовательности в F #

let a = [(),1;(),4;(),3;] 

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

let rec repeat avalue n = seq { if n > 0 then 
            yield avalue; yield! repeat avalue (n-1) } 

let b = seq { for v,n in a do 
       yield! repeat v n } |> Seq.toList 

Есть ли способ выразить это inline, в виде композиции?

let c = a |> Seq.XXX(fun e -> ...) 

ответ

6

Вы можете сделать это с помощью Enumerable.Repeat:

> Seq.collect Enumerable.Repeat [ 1, 2; 3, 4; 5, 6 ] |> List.ofSeq;; 
val it : int list = [1; 1; 3; 3; 3; 3; 5; 5; 5; 5; 5; 5] 
+0

ах, я не знаю, что один! – nicolas

+1

Итак, это один из лучших для кортежей, что является контекстом моего вопроса. Следовательно, это самый функциональный ответ. – nicolas

+2

Теперь также ['List.replicate <'T>'] (https://msdn.microsoft.com/en-us/library/ee353665.aspx). –

3

Как насчет

let c = a |> Seq.collect (fun (v,i) -> [1..i] |> Seq.map (fun x -> v)) 

Я не знаю, библиотечную функцию, аналогичную Enumerable.Repeat; если кто-то знает один, добавьте комментарий.

EDIT

Я нашел библиотечную функцию, аналогичную Enumerable.Repeat, хотя в List модуле:

let c = a |> Seq.collect (fun (v,i) -> List.replicate i v) 

Это было бы более элегантно, если пары в источнике Последовательность была отменена:

let c = a |> Seq.collect ((<||) List.replicate) 

Так что кажется, что Enumerable.Re торф (как в принятом ответе) действительно делает лучшее решение, так как его tupled аргумент соответствует последовательности элементов:

let c = a |> Seq.collect Enumerable.Repeat 

Если кто-нибудь знает о столь же элегантное решение, которое остается в пределах # библиотеки F, пожалуйста, добавить комментарий ; Благодарю.

+0

Ничего, я не знал, что существует функция F # ('<||'), похожая на Hascell 'uncurry'! – MisterMetaphor

3
let rec repeat (item,n) = seq { if n > 0 then yield item; yield! repeat(item, n-1)} 
a |> Seq.collect repeat 

Например,

[('a',2); ('b',2)] |> Seq.collect repeat 

val it: seq<char> = seq ['a';'a';'b';'b'] 
+0

красивый. хотя это |> Seq.collect (fun (item, n) -> repeat item n) – nicolas

+1

Моя версия с чередующимся аргументом 'repeat' позволяет избавиться от лямбда в комбинаторе. –

Смежные вопросы