Tengo una secuencia con {"1";"a";"2";"b";"3";"c";...}
.cómo obtener pares de valores consecutivos de F # Seq
¿Cómo puedo transformar esta ss en {("1","a");("2","b");("3","c");...}
Tengo una secuencia con {"1";"a";"2";"b";"3";"c";...}
.cómo obtener pares de valores consecutivos de F # Seq
¿Cómo puedo transformar esta ss en {("1","a");("2","b");("3","c");...}
Puede utilizar concordancia con el modelo de la siguiente manera:
let list = ["1";"2";"3";"4";"5";"6"]
let rec convert l =
match l with
x :: y :: z -> (x,y) :: convert z
| x :: z -> (x,x) :: convert z
| [] -> []
let _ =
convert list
pero usted tiene que decidir qué hacer si la lista tiene un número impar de elementos (en mi solución se produce de un par con mismo valor)
(No sé si hay construcciones inteligentes en F #, estoy acostumbrado a OCaml :) – Jack
esto funcionaría si fuera una lista, pero tengo una secuencia muy grande. no estoy seguro de si este enfoque de coincidencia de patrones funcionará en una secuencia – functional
¿por qué no debería funcionar? Pasa por la lista y crea la nueva por concatenación. Debería ser una complejidad lineal ... ¿o le preocupa el desbordamiento de pila? – Jack
Aquí es una solución mucho-demasiado-inteligente:
let s = ["1";"a";"2";"b";"3";"c"]
let pairs s =
s |> Seq.pairwise
|> Seq.mapi (fun i x -> i%2=0, x)
|> Seq.filter fst
|> Seq.map snd
printfn "%A" (pairs s)
sublime ........ – Indy9000
Los enumeradores no siempre son malvados.
let pairs (source: seq<_>) =
seq {
use iter = source.GetEnumerator()
while iter.MoveNext() do
let first = iter.Current
if iter.MoveNext() then
let second = iter.Current
yield (first, second)
}
Aquí está el código # fuente F del Seq.pairwise
tomado de FSharp.Core/seq.fs
[<CompiledName("Pairwise")>]
let pairwise (source: seq<'T>) = //'
checkNonNull "source" source
seq { use ie = source.GetEnumerator()
if ie.MoveNext() then
let iref = ref ie.Current
while ie.MoveNext() do
let j = ie.Current
yield (!iref, j)
iref := j }
"Los enumeradores no siempre son malvados" +1 a ese . – AruniRC
Aquí hay una variación en @ solución de Brian:
["1";"a";"2";"b";"3";"c";"4";"d";"5";"e";"6";"f"]
|> Seq.pairwise
|> Seq.mapi (fun i x -> if i%2=0 then Some(x) else None)
|> Seq.choose id
Y aquí está un cerebro-fusor con Seq.scan :
["1";"a";"2";"b";"3";"c";"4";"d";"5";"e";"6";"f"]
|> Seq.scan (fun ((i,prev),_) n -> match prev with
| Some(n') when i%2=0 -> ((i+1,Some(n)), Some(n',n))
| _ -> ((i+1,Some(n)), None))
((-1,None), None)
|> Seq.choose snd
Puede considerar el uso de LazyLists para esto.
let (|Cons|Nil|) = LazyList.(|Cons|Nil|)
let paired items =
let step = function
| Cons(x, Cons(y, rest)) ->
Some((x, y), rest)
| _ ->
None
Seq.unfold step (LazyList.ofSeq items)
Como F # 4.0, ahora se puede utilizar chunkBySize
let source = seq ["1";"a";"2";"b";"3";"c"]
let pairs source =
source
|> Seq.chunkBySize 2
|> Seq.map (fun a -> a.[0], a.[1])
;;
printfn "%A" (pairs source)
Aquí es una respuesta relacionada que pueden interesarle: http://stackoverflow.com/questions/833180/handy-f-snippets/2271132 # 2271132, aunque es para listas, no para Seq. – Benjol