Jack Rus
Jack Rus

Reputation: 145

Fatal error: Index out of range (Arrays)

I very new to Swift and programming in general, so I can't figure out where is the problem. Tried to find the answer in the existing topics - couldn't. Thanks in advance.

func smartAssigning(names: [String], statuses: [Bool], projects: [Int], tasks: [Int]) -> String {
    //beginig
    var collect: [Int] = [], nameLast = 0
    var candidateNumber: [Int] = []
    for x in 0...statuses.count {

        //Defines who is working
        if statuses[x] == false {
            collect.append(x)
        } else {}
    }

    // Checks for min tasks assigned among those not on vacation
    let rt: Int = tasks.min()!
    let rp: Int = projects.min()!
    for i in collect {
        if tasks[i] == rt {
            candidateNumber.append(i)
        } else {}
    }
    // if there is only 1 with min tasks - returns his number in array
    if candidateNumber.count == 1 {
        nameLast = candidateNumber[0]
    } else {
        // checks for min projects
        for e in candidateNumber {
            if projects[e] == rp {
                nameLast = e
            }
        }
    }
    return names[nameLast]
}
smartAssigning(names: ["sd", "dfsd","dfsdf"], statuses: [true, false, false], projects: [2, 1, 1], tasks: [3, 2, 1])

Screen:

Screen

Upvotes: 1

Views: 2094

Answers (1)

Alexander
Alexander

Reputation: 63397

The error is here:

for x in 0...statuses.count { // Error is here

    //Defines who is working
    if statuses[x] == false {
        collect.append(x)
    } else {}
}

If statuses.count is n, then the maximum index is n-1. It should be 0..<statuses.count. You should avoid manually creating such a range, exactly because it can cause this typo. It's much better to just do for x in status.indices.

On a side note, you don't need to have an else clause if it doesn't do anything.

Also, rather than comparing against false (== false), just negate the Bool.

for x in statuses.indices { // Error is here
    //Defines who is working
    if !statuses[x] {
        collect.append(x)
    }
}

This whole code can be written using a single filter(_:) expression:

// TODO: Give me a new meaningful name!
let collect = statues.enumerated() // Get index, status pairs
                     .filter{ index, status in !status } // filter all false statuses
                     .map{ index, status in index } // Take just the indices

Upvotes: 1

Related Questions