0

I am in process of learning swift and web services.

When I tried to compile the following code in IOS 9, I get

reduce is unavailable: call the reduce() method on the sequence

private class func urlWithName(name: String, var args: [String: String]) -> NSURL
{
    args["username"] = "ijoshsmith"
    let
    baseURL      = "http://api.geonames.org/",
    queryString  = queryWithArgs(args),
    absolutePath = baseURL + name + "?" + queryString
    return NSURL(string: absolutePath)!
}

private class func queryWithArgs(args: [String: String]) -> String
{
    let parts: [String] = reduce(args, [])
        {
            result, pair in
            let
            key   = pair.0,
            value = pair.1,
            part  = "\(key)=\(value)"
            return result + [part]
    }
    return (parts as NSArray).componentsJoinedByString("&")
}  

So, I understand that I should covert reduce(args, []) to something like args.reduce(initial: T, combine:(T, Self.Generator.Element) throws -> T). Can someone help me in explaining and converting it.

thanks.

2
  • The error the compiler gave means that - You can use the reduce method on arrays(sequence).The high order functions like, map(), reduce() & filter() are meant to be used with Sequence / Array. Commented Oct 13, 2015 at 6:30
  • Also Please follow this link : weheartswift.com/… to learn more about the higher order functions. Trust me they're very useful. :) HTH Commented Oct 13, 2015 at 6:31

2 Answers 2

2

let parts: [String] = reduce(args, [])

You're trying to call reduce as a standalone function, but it's actually a method in the SequenceType protocol, which is adopted by Array. Assuming that args is the array to which you want to apply reduce, you'd call it like:

foo = args.reduce(t, f)

where t is the initial value and f is the combining function.

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

6 Comments

Just to add a point, the result of the reduce() will be of type 't'
A minor clarification: it's not a member function of arrays, it's part of SequenceType.
@AaronBrager SequenceType is the protocol that declares reduce(), but Array still has to provide the implementation. It's a good point to mention SequenceType, though, and I'll add that. Thanks.
If I recall correctly, it's implemented as a default protocol implementation, not on Array, according to a stack trace I looked at. I might be remembering wrong though.
Here's the stack trace I was thinking of - my interpretation might be wrong though. Let me know what you think
|
1

The correct syntax looks like this:

private class func queryWithArgs(args: [String: String]) -> String
{
    let parts: [String] = args.reduce([]) {
            result, pair in
            let
            key   = pair.0,
            value = pair.1,
            part  = "\(key)=\(value)"
            return result + [part]
    }
    return parts.joinWithSeparator("&")
}

I also updated your return value to avoid an NSArray cast.

You might also want to see Alamofire's ParameterEncoding.swift, which has a more thorough approach to parameter encoding already written.

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.