1

My array is of type [[Int]]

array = [[1,2,3],
         [4,5,6],
         [7,8,9,10],
         [11,12,13],
         [14,15,16]]

I want the transpose result as:

array = [[1,4,7,11,14],
         [2,5,8,12,15],
         [3,6,9,13,16],
         [0,0,10,0,0]]

How to pad 0's to an array which does not have an equal row or column mapping.

I want the transpose to work for both rows and columns with unequal mapping elements. Please help.

Bella
  • 88
  • 1
  • 15
  • Firstly, I would include a bounds-checked array lookup, discussed [here](https://stackoverflow.com/a/30593673/3151675). – Tamás Sengel Jul 31 '17 at 10:05
  • @the4kman It did not work. Can u please tell how to pad 0's while transforming the matrix for unequal rows or columns. – Bella Jul 31 '17 at 11:37

4 Answers4

6

Here is an implementation that does what you want:

func transpose(_ input: [[Int]]) -> [[Int]] {
    let columns = input.count
    let rows = input.reduce(0) { max($0, $1.count) }

    var result: [[Int]] = []

    for row in 0 ..< rows {
        result.append([])
        for col in 0 ..< columns {
            if row < input[col].count {
                result[row].append(input[col][row])
            } else {
                result[row].append(0)
            }
        }
    }

    return result
}

Or, alternatively:

func transpose(_ input: [[Int]]) -> [[Int]] {
    let columns = input.count
    let rows = input.reduce(0) { max($0, $1.count) }

    return (0 ..< rows).reduce(into: []) { result, row in
        result.append((0 ..< columns).reduce(into: []) { result, column in
            result.append(row < input[column].count ? input[column][row] : 0)
        })
    }
}
Rob
  • 415,655
  • 72
  • 787
  • 1,044
0

You should try this:

Swift 3

var array = [[1,2,3,4],[5,6,7,8],[9,10,11],[12,13,14]]
var arraytrans = [[Int]]()

override func viewWillAppear(_ animated: Bool)
{
    for i in stride(from: 0, to: array.count, by: 1)
    {
        var subArray = [Int]()
        for j in stride(from: 0, to: array.count, by: 1)
        {
            if array[i].count < array.count
            {
                array[i].append(0)
            }
            subArray.append(array[j][i])
        }
        arraytrans.append(subArray)
    }
    print(self.arraytrans) 
}
Pragnesh Vitthani
  • 2,532
  • 20
  • 28
0

Thanks..! @Pragnesh Vitthani I just modified your answer.

var array = [[1,2,3],
             [4,5,6],
             [7,8,9,10],
             [11,12,13],
             [14,15,16]]

var transposedArray = [[Int]]

for i in stride(from: 0, to: array.count, by: 1)
{
    var subArray = [Int]()
    for j in stride(from: 0, to: array.count, by: 1)
    {
        if array[j].count < array.count
        {
            array[j].append(0)
        }
        subArray.append(array[j][i])
    }
    transposedArray.append(subArray )
}
print(transposedArray)
Bella
  • 88
  • 1
  • 15
  • 1
    What is the difference to Pragnesh Vitthani's answer? – Martin R Aug 17 '17 at 13:40
  • @MartinR I was getting IndexOutOfBounds exception. But now I want to be Equal, before transposing it. I don't get the desired output by using the above answers since array element length in array2 is greater than number of array elements. – Bella Aug 17 '17 at 13:51
0

A generic version based on @Rob's solution:

func transpose<T>(_ input: [[T]], defaultValue: T) -> [[T]] {
    let columns = input.count
    let rows = input.reduce(0) { max($0, $1.count) }

    return (0 ..< rows).reduce(into: []) { result, row in
        result.append((0 ..< columns).reduce(into: []) { result, column in
            result.append(row < input[column].count ? input[column][row] : defaultValue)
        })
    }
}

Usage: call transpose(srings, defaultValue: "") or transpose(integers, defaultValue: 0).

superarts.org
  • 7,009
  • 1
  • 58
  • 44