1

I don't understand why I am getting the following error when executing this function:

error: unexpected non-void return value in void function return [index, dic[value]!]

func findIndexes(_ nums: [Int], _ target: Int) -> [Int] {
    var dic = [Int:Int]()
    var answer: [Int] = []
    nums.enumerated().forEach { index, value in
        
        //the goal is to get the index of the value matching the difference
        //check if current value == anything in dictionary
        
        //MARK: Add the Index and Difference to Dictionary
        let difference = (target - value)
        if (dic.keys.contains(value) && !dic.values.contains(index)) {
            return [index, dic[value]!]
        }
        dic[difference] = index
    }
    return []
}

print(findIndexes([0,11,15,2,7], 9))
3
  • 2
    You don't get it when executing anything. It's a compile error. Commented Aug 28, 2022 at 1:36
  • You're correct, I was testing in playground which does not show compile errors until executing..what causes this error in my code? Array should be returned either empty or not, how is it written incorrectly. Commented Aug 28, 2022 at 1:38
  • 1
    Don't test in a playground. The error messages are not, by and large, useful. Commented Aug 28, 2022 at 1:44

1 Answer 1

2

I'm unclear what you're trying to do, but this is a version of what you are doing that compiles:

func findIndexes(_ nums: [Int], _ target: Int) -> [Int] {
    var dic = [Int:Int]()
    var answer: [Int] = []
    for (index, value) in nums.enumerated() {
        let difference = (target - value)
        if (dic.keys.contains(value) && !dic.values.contains(index)) {
            return [index, dic[value]!]
        }
        dic[difference] = index
    }
    return []
}

Why the difference? for...in is a loop. You can return from the surrounding function from within it, break out of it, etc. forEach loops implicitly but it is not a loop; it takes a closure, and you can't return out of that unless it's a closure that yields a return value, and this one doesn't; its type, as you can see from the docs, is (Self.Element) throws -> Void — and Void means "no return value".

If you insist on using forEach, you can do what you're trying to do with a bit of extra jiggery-pokery:

func findIndexes(_ nums: [Int], _ target: Int) -> [Int] {
    var dic = [Int:Int]()
    var answer: [Int] = []
    nums.enumerated().forEach { index, value in
        let difference = (target - value)
        if (dic.keys.contains(value) && !dic.values.contains(index)) {
            answer = [index, dic[value]!]
            return
        }
        dic[difference] = index
    }
    return answer
}

I think that does what you're trying to do, but I'm not sure; it seems unnecessarily obscure. In my personal opinion, the way to program is to Say What You Mean (SWYM).

Sign up to request clarification or add additional context in comments.

5 Comments

The main difference I see is that I am using a trailing closure in a forEach and you are using a for loop..is have a return inside a closure wrong? Genuinely asking, I am currently learning
I've added further explanation in an edit to my answer. Basically you're correct!
I added a forEach variant that I think gives the same result.
Just to clarify, the reason you were able to return inside forEach in your second response, was because you technically returned nothing which is still acceptable for a closure that yields no return value correct?
Exactly so. I passed the value out by assignment instead of returning it.

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.