Sunny Singh
Sunny Singh

Reputation: 3

unable to infer complex closure return type

unable to build swift project because of this error.

// showing error with inputs.flatmap

    fileprivate func makeShippingAddressDictWith(inputs: [TextFieldData]) -> [String: String] {
        var shippingDict: [String: String] = [:]

        let _ = inputs.flatMap { input in
            if let shippingFieldType = input.type as? ShippingDictKeyable.Type {
                shippingDict[shippingFieldType.shippingDictKey] = input.text
            }
            return nil
        }

        // FIXME: these empty values are the result of a poorly designed request in GDKECommerce

        shippingDict["email"] = ""
        shippingDict["second_name"] = ""
        shippingDict["suffix"] = ""
        shippingDict["title"] = ""
        shippingDict["salutation"] = ""
        shippingDict["company_name"] = ""

        return shippingDict
    }
}

Upvotes: 0

Views: 1128

Answers (1)

Alain T.
Alain T.

Reputation: 42139

You could use .forEach instead of .flatMap. Then you would not have to worry about a return type that you are ignoring anyway (with let _ =).

Combining this with a filter would produce a cleaner functional statement if that's what you're after:

inputs.map{ ( $0.text, $0.type as? ShippingDictKeyable.Type) }
      .filter{ $1 != nil }
      .forEach{ shippingDict[$1!.shippingDictKey] = $0 }

// FIXME: these empty values are the result of a poorly designed request in GDKECommerce

let blankAttributes = ["email", "second_name", "suffix", "title", "salutation", "company_name"]
blankAttributes.forEach{ shippingDict[$0] = "" }

Or use a for loop as suggested by Hamish.

If performance is a factor, the compiler will produce faster code with the for loop than with map/filter/forEach.

Note that, if you want to go crazy with functional style, Swift 4 will let you return the whole dictionary in a single line:

return [String:String]( uniqueKeysWithValues:
                        inputs.map{ ($0.type as? ShippingDictKeyable.Type, $0.text) }
                              .filter{ $0.0 != nil }
                              .map{($0!.shippingDictKey,$1)}
                        + ["email", "second_name", "suffix", "title", "salutation", "company_name"]
                          .map{($0,"")}
                      )

This may only work in the playground though cause real projects tend to complain about expressions being too complex more often.

Upvotes: 0

Related Questions