Home > Software engineering >  Transposing without recursion
Transposing without recursion

Time:10-25

How do I go about creating a function which will transpose a list without using recursion?

This is what I've gotten so far:

let lst = [[1;2;3];[4;5;6];[7;8;9]]
let transpLstLst (lst: 'a list list) -> 'a list list =
    List.map List.head lst :: []

Which returns:

[[1;4;7]]

This is a long the lines of the output I want, but how do I go from that to being able to get to this output:

[[1;4;7];[2;5;8];[3;6;9]]

CodePudding user response:

This is very inefficient*, but it meets your requirements:

let transpose (matrix : List<List<_>>) =
    [
        if matrix.Length > 0 then
            assert(matrix |> List.distinctBy List.length |> List.length = 1)
            for i = 0 to matrix.[0].Length - 1 do
                yield [
                    for list in matrix do
                        yield list.[i]
                ]
    ]

Example:

let matrix = [[1; 2; 3]; [4; 5; 6]; [7; 8; 9]; [10; 11; 12]]
transpose matrix |> printfn "%A"   // [[1; 4; 7; 10]; [2; 5; 8; 11]; [3; 6; 9; 12]]

* O(n3) where n is the length of a square matrix.

CodePudding user response:

For better performance, you can convert the list of list to an Array2D, and then create your transposed list from the Array2D.

let transpose' xss =
    let xss  = array2D xss
    let dimx = Array2D.length1 xss - 1
    let dimy = Array2D.length2 xss - 1
    [   for y=0 to dimy do [
            for x=0 to dimx do 
                yield xss.[x,y]
        ]
    ]

For non-learning purpose, you should use the built-int List.transpose

 List.transpose lst
  • Related