F # convert array to array of tuples

Let's say I have an array

let arr = [|1;2;3;4;5;6|]

      

I would like to convert it to something like

[|(1,2);(3,4);(5,6)|]

      

I've seen Seq.window but this one will generate something like

[|(1,2);(2,3);(3,4);(4,5);(5,6)|]

      

what I do not want

+3


source to share


4 answers


You can use Array.chunkBySize and then match each submatrix in tuples:



let input = [|1..10|]
Array.chunkBySize 2 list |> Array.map (fun xs -> (xs.[0], xs.[1]))

      

+3


source


@ Slugart's accepted answer is a better approach (IMO) assuming you know the array has an even number of elements, but here's a different approach that doesn't throw an exception if an odd number happens there (this just omits the last trailing element):



let arr = [|1;2;3;4;5|]
seq { for i in 0 .. 2 .. arr.Length - 2 -> (arr.[i], arr.[i+1]) } |> Seq.toArray

      

+1


source


You can use Seq.pairwise

if you are filtering out all other tuples. Filtering should pass state through iteration, which is usually done by a function scan

.

[|1..10|]
|> Seq.pairwise
|> Seq.scan (fun s t ->
    match s with None -> Some t | _ -> None )
    None
|> Seq.choose id
|> Seq.toArray
// val it : (int * int) [] = [|(1, 2); (3, 4); (5, 6); (7, 8); (9, 10)|]

      

But then it is also possible that it scan

generates tuples directly, in case of an intermediate array penalty.

[|1..10|]
|> Array.scan (function
| Some x, _ -> fun y -> None, Some(x, y)
| _  -> fun x -> Some x, None )
    (None, None)
|> Array.choose snd

      

0


source


Use Seq.pairwise

to turn a sequence into tuples

[|1;2;3;4;5;6|]
    |> Seq.pairwise
    |> Seq.toArray

val it : (int * int) [] = [|(1, 2); (2, 3); (3, 4); (4, 5); (5, 6)|]

      

Should be:

let rec slice =
    function
    | [] -> []
    | a::b::rest -> (a,b) :: slice (rest)
    | _::[] -> failwith "cannot slice uneven list"

      

-1


source







All Articles