如何从F#Seq中获取连续值对
我有一个序列,如何从F#Seq中获取连续值对,f#,sequence,F#,Sequence,我有一个序列,{“1”;“a”;“2”;“b”;“3”;“c”…} 如何将该序列转换为{(“1”,“a”);(“2”,“b”);(“3”,“c”);…}您可以通过以下方式使用模式匹配: 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) :: conve
{“1”;“a”;“2”;“b”;“3”;“c”…}
如何将该序列转换为
{(“1”,“a”);(“2”,“b”);(“3”,“c”);…}
您可以通过以下方式使用模式匹配:
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
但是,如果列表中的元素数量为奇数(在我的解决方案中,会生成一对具有相同值的元素),您必须决定该怎么做。这里有一个非常聪明的解决方案:
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)
["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
统计员并不总是邪恶的
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)
}
以下是@Brian解决方案的一个变体:
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)
["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
这是一个使用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
你可以考虑使用LaZyListSub。
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)
自F#4.0以来,您现在可以使用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)
(我不知道在F#中是否有聪明的构造,我习惯于OCaml:)如果它是一个列表,这会起作用,但我有一个非常大的seq。不确定这种模式匹配方法是否适用于Seqwhy不能工作?它遍历列表并通过连接构建新列表。它应该是线性复杂度。。或者你担心堆栈溢出?哦,你的意思是你想让它保持懒惰?@functional:这是相同的代码,但使用延续传递使其尾部递归这里有一个相关的答案,你可能会感兴趣:,尽管它是针对列表,而不是Seq。“枚举数并不总是邪恶的”+1。这对我来说很有意思!但是我们应该考虑使用SEQ.TryItIt检索索引值。如果源列表的值为奇数,则可能引发异常。