2

I've been trying to get this function to return a Bool value but I don't understand why i'm getting the error "missing return in a function expected to return 'Bool'. I've been looking around online and tried different things but I can't seem to find a solution. Any help would be appreciated!

func trueSquare(a:[Int], b:[Int]) -> Bool {
    for i in b[0]...b.endIndex {
        if b[i] == a[i]*a[i] {
            return true
        }
        else {
            return false
        }
    }
}

EDIT: I have changed the loop to for i in 0...(b.count - 1) but I am still getting the same error even when I call the function with a and b both having the same numbers of elements.

7
  • You get that error because what happens if b array is empty and you can never run for loop? Also, you try to check if b[i] == a[i]*a[i] but this will crash if a has less less elements than b. Commented Jan 23, 2019 at 20:09
  • What if b.endIndex was less than b[0]? Commented Jan 23, 2019 at 20:09
  • 2
    Something like return zip(a, b).contains(where: { $0 * $0 == $1 }) might be an easier way to get the result. Commented Jan 23, 2019 at 20:15
  • 3
    On top of everything else that's been said, the loop never goes past the first iteration in any case. Commented Jan 23, 2019 at 20:22
  • 1
    @DanHilton You can't have any use of return inside the loop if you wish to iterate the whole loop. Commented Jan 23, 2019 at 22:24

3 Answers 3

4

What if your array has no element? Then for each loop never runs and then your method returns nothing which is obviously wrong. So you need to return value even outside of the loop.


But, your logic is bad. You're returning boolean value depending on if just first element from b is equal to a*a.

So, logic should be something like: if every element meets the condition, then return true, otherwise, return false. To achieve this, in Swift 4.2+ you can use method allSatisfy

func trueSquare(a:[Int], b:[Int]) -> Bool {
    guard a.count == b.count else { return false } // if arrays have different number of elements, return false
    return a.enumerated().allSatisfy {$0.element * $0.element == b[$0.offset]}
}
Sign up to request clarification or add additional context in comments.

Comments

2

I suspect the compiler requires a return value for the case when the loop is not executed at all.

Now, a ClosedRange can never be empty, so b[0]...b.endIndex won't ever be empty (if it results in an empty or invalid range, the code would crash), but the compiler is not smart enough to know that.

PS: Are you sure b[0]...b.endIndex is actually the sequence you want to loop over. This creates a range from the first element of b to the endIndex of b. That doesn't make any sense to me.

1 Comment

I've changed the loop to 'for i in 0...(b.count - 1)' and I've tried setting a:[4, 8, 16, 20], b:[16, 64, 122, 200] but still getting the same error
1

Your function does not handle case where b is an empty array. You need to define what you want the return value to be for such case, because your loop will be skipped when b is an empty array.

Secondly, your logic is also incomplete, because if the condition is good for i==0, you immediately return true, without checking the rest of the items.

Thirdly, you probably want to make sure a and b have same length.

So here is what your function should look like:

func trueSquare(a:[Int], b:[Int]) -> Bool {
    if a.count != b.count {
        return false
    }
    for i in 0..<b.count {
        if b[i] != a[i]*a[i] {
            return false
        }
    }
    return true
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.