Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从F#Seq中获取连续值对_F#_Sequence - Fatal编程技术网

如何从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检索索引值。如果源列表的值为奇数,则可能引发异常。