简体   繁体   中英

Filling the Multidimensional Array in Swift

I'm newbie to Swift and I got a problem with Swift language.

I should make a function, which creates a 2-dimensional matrix NxN and finds sum of diagonally situated elements. I've got some problem with filling an array with random values.

That's my code:

import Foundation
func diagonal (N:Int) {
    var array: [[Int]] = [[0],[0]]
    for row in 0...N {
        for col in 0...N {
            var z = Int(arc4random_uniform(100))
            array[row][col] = z
        }
    }
    println (array)
}    

It doesn't work.

So I'm looking forward for your help.

@matt's answer makes some good points about your current code and highlights the things you need to fix. I wanted to provide an alternative answer to filling the two-dimensional array. Instead of populating the arrays with zeros and then setting each row/column value, you could use append to add new values, for example:

func diagonal (N:Int) {
    var array: [[Int]] = []

    for row in 0..<N {
        // Append an empty row.
        array.append([Int]())

        for _ in 0..<N {
            // Populate the row.
            array[row].append(Int(arc4random_uniform(100)))
        }
    }

    println(array)
}

Using it:

diagonal(2)
// [[40, 58], [44, 83]]

You are saying:

array[row][col] = z

There are no "sparse" arrays in Swift. If row does not exist — that is, if array[row] refers to an index larger than the last existing index of array — then you will crash. You cannot simply assign to array[row][col] and expect magic to happen; you must ensure that array[row][col] exists .

Another problem is that you have confused the range operator ... with ..< . In your loops for row in 0...N you are going to loop N+1 times, as if the arrays consisted of N+1 elements. That is probably not what you want; you probably intended N to represent the number of elements. So you need to use ..< instead.

Thus, to sum up everything I've just said and put it into action, your code will run without crashing if you replace the relevant three lines like this:

var array: [[Int]] = Array(count:N, repeatedValue:Array(count:N, repeatedValue:0))
for row in 0..<N {
    for col in 0..<N {

That is not the only way or even the best way to do what you are trying to do, but at least it makes sense, which is more than your code can claim!

public func  getLine() -> String {

    var buf = String()
    var c = getchar()

    while c != EOF && c != 10 {
        buf.append(Character(UnicodeScalar(UInt32(c))!))
        c = getchar()
    }
    return buf
}


print("Enter value of Rows and Coloums :")

let rows = Int(getLine())
let coloums = Int(getLine())

print("Enter values in Array(rows * coloums):")

var array = [[Int]]()

for i in 0 ..< (rows ?? 0){

    var rowArray = [Int]()

    for j in 0 ..< (coloums ?? 0) {

        rowArray.append(Int(getLine())!)
    }

    array.append(rowArray)
}

print(array)

The two answers above cover all of the highlights and rectify the issue that the OP encountered. However, they are a bit dated and lack flexibility.

The following provides a custom initializer on [Int] to support populating a 2D array with random values.

extension Array where Element == [Int] {
    init(row: Int, col: Int, min: Int, max: Int) {
        precondition(min <= max)
        self.init()
        for index in 0..<row { 
            append([Int]())
            for _ in 0..<col {
                self[index].append(Int.random(in: min...max))
            }
        }
    }
}

A quick overview of what is going on:

  1. Precondition ensures that the min value does not exceed max , otherwise your random function will crash
  2. An empty [Int] is created
  3. It iterates for the row count, creating an empty [Int] that is added to itself
  4. Then it iterates again down each column, appending a random Int within your defined range

You can call it with this:

let matrix = [[Int]](row: 10, col: 10, min: 0, max: 99)

As an aside, if you want an equal count of row & col, you can make another init that accepts a single size, and then calls into this one (or just replace row/col with size).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM