idiomatic way to unwrap many optional NSDictionary elements?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

idiomatic way to unwrap many optional NSDictionary elements?

Jean-Denis Muys
I have a dictionary coming from the parsing of a JSON (coming from an outside source). I want to store the values that are present in fixed properties, something similar to:

func feedJSONdata(jsonDict: NSDictionary) {
  var1 = jsonDict["var1"] as! String
  var2 = jsonDict["var2"] as! String
  var3 = jsonDict["var3"] as! String
  var4 = jsonDict["var4"] as! String
  var5 = jsonDict["var5"] as! String
 // and so on
}

Is there a way to guard against any of the entries in the dictionary to be missing?

Repeating:

if let var1Entry = jsonDict["var1"] as? String {
    var1 = var1Entry
}

seems heavy handed to me. Any lighter option?

Second, I may also want to guard against the dictionary entry being present but not a string.

Thanks,

Jean-Denis




--
You received this message because you are subscribed to the Google Groups "Swift Language" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/swift-language/0317002f-f4d7-45ca-9fc6-f38758c93fa2%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: idiomatic way to unwrap many optional NSDictionary elements?

Jens Alfke

On Jul 16, 2015, at 6:56 AM, Jean-Denis Muys <[hidden email]> wrote:

Is there a way to guard against any of the entries in the dictionary to be missing?

Depends what you want the fallback behavior to be. It’s easy to fall back to a default value:

var1 = jsonDict["var1"] as? String ?? ""

If you want to skip assigning it at all, you can write a little helper function, called like
assignIfPresent(jsonDict, “var1”, &var1)

But yeah, binding between JSON and statically-typed languages can be a pain. The best implementation I’ve seen is Go’s  which is really simple and convenient — what you’re asking for would be a trivial one-liner in Go. But it takes advantage of reflection capabilities that Swift doesn’t have.

—Jens

--
You received this message because you are subscribed to the Google Groups "Swift Language" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/swift-language/975627C3-4A3E-43D6-935F-24BC520AA558%40mooseyard.com.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: idiomatic way to unwrap many optional NSDictionary elements?

Marco S Hyman
In reply to this post by Jean-Denis Muys

> func feedJSONdata(jsonDict: NSDictionary) {
>   var1 = jsonDict["var1"] as! String
>   var2 = jsonDict["var2"] as! String
>   var3 = jsonDict["var3"] as! String
>   var4 = jsonDict["var4"] as! String
>   var5 = jsonDict["var5"] as! String
>  // and so on
> }

if let var1 = jsonDict["var1"] as? String where !var1.isEmpty,
   let var2 = jsonDict["var2"] as? String where !var2.isEmpty,
   let var3 = jsonDict["var3"] as? String where !var3.isEmpty,
   let var4 = jsonDict["var4"] as? String where !var4.isEmpty,
   let var5 = jsonDict["var5"] as? String where !var5.isEmpty {
    // all vars are strings and not empty
    // ...
} else {
    // error
}

Marc





--
You received this message because you are subscribed to the Google Groups "Swift Language" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/swift-language/FD0BCB14-35A4-400A-91A7-8A0BEB7AF8D2%40snafu.org.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: idiomatic way to unwrap many optional NSDictionary elements?

Marco S Hyman
I wrote....


>> func feedJSONdata(jsonDict: NSDictionary) {
>>  var1 = jsonDict["var1"] as! String
>>  var2 = jsonDict["var2"] as! String
>>  var3 = jsonDict["var3"] as! String
>>  var4 = jsonDict["var4"] as! String
>>  var5 = jsonDict["var5"] as! String
>> // and so on
>> }
>
> if let var1 = jsonDict["var1"] as? String where !var1.isEmpty,
>   let var2 = jsonDict["var2"] as? String where !var2.isEmpty,
>   let var3 = jsonDict["var3"] as? String where !var3.isEmpty,
>   let var4 = jsonDict["var4"] as? String where !var4.isEmpty,
>   let var5 = jsonDict["var5"] as? String where !var5.isEmpty {
>    // all vars are strings and not empty
>    // ...
> } else {
>    // error
> }

This works too and might be closer to what you want.

func feedJSONdata(jsonDict: NSDictionary) {

 {
    guard let var1 = jsonDict["var1"] as? String where !var1.isEmpty,
          let var2 = jsonDict["var2"] as? String where !var2.isEmpty,
          let var3 = jsonDict["var3"] as? String where !var3.isEmpty,
          let var4 = jsonDict["var4"] as? String where !var4.isEmpty,
          let var5 = jsonDict["var5"] as? String where !var5.isEmpty else {
        print("Missing required variables")
        return
    }
    print("vars are OK”)
    // work with vars here
}

--
You received this message because you are subscribed to the Google Groups "Swift Language" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/swift-language/18A98D4E-D659-4AFA-AE25-FD3C2E6062E9%40snafu.org.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: idiomatic way to unwrap many optional NSDictionary elements?

Bruno Berisso
You can also do something like:

func feedJSONdata(jsonDict: NSDictionary) {

    //Get a dictionary with values of type String (filter non string and nil values)
    let dictWithCuratedValues = jsonDict.filter { ($1 is String) }
    
    //Check if the curated version has valid data (ex: dictWithCuratedValues.count > numberOfFileds, etc)
    ....
}

I'm not sure if 'filter' is available in Swift 2, but for prior version you will need to add some extra code to give Dictionary the ability to filter his elements:

extension Dictionary {
    init(_ pairs: [Element]) {
        self.init()
        for (k, v) in pairs {
            self[k] = v
        }
    }

    func filter(includeElement: Element -> Bool) -> [Key: Value] {
        return Dictionary(Swift.filter(self, includeElement))
    }
}

2015-07-17 18:45 GMT-03:00 Marco S Hyman <[hidden email]>:
I wrote....


>> func feedJSONdata(jsonDict: NSDictionary) {
>>  var1 = jsonDict["var1"] as! String
>>  var2 = jsonDict["var2"] as! String
>>  var3 = jsonDict["var3"] as! String
>>  var4 = jsonDict["var4"] as! String
>>  var5 = jsonDict["var5"] as! String
>> // and so on
>> }
>
> if let var1 = jsonDict["var1"] as? String where !var1.isEmpty,
>   let var2 = jsonDict["var2"] as? String where !var2.isEmpty,
>   let var3 = jsonDict["var3"] as? String where !var3.isEmpty,
>   let var4 = jsonDict["var4"] as? String where !var4.isEmpty,
>   let var5 = jsonDict["var5"] as? String where !var5.isEmpty {
>    // all vars are strings and not empty
>    // ...
> } else {
>    // error
> }

This works too and might be closer to what you want.

func feedJSONdata(jsonDict: NSDictionary) {

 {
    guard let var1 = jsonDict["var1"] as? String where !var1.isEmpty,
          let var2 = jsonDict["var2"] as? String where !var2.isEmpty,
          let var3 = jsonDict["var3"] as? String where !var3.isEmpty,
          let var4 = jsonDict["var4"] as? String where !var4.isEmpty,
          let var5 = jsonDict["var5"] as? String where !var5.isEmpty else {
        print("Missing required variables")
        return
    }
    print("vars are OK”)
    // work with vars here
}

--
You received this message because you are subscribed to the Google Groups "Swift Language" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/swift-language/18A98D4E-D659-4AFA-AE25-FD3C2E6062E9%40snafu.org.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "Swift Language" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/swift-language/CA%2BaYCteSFx0ooa0e6UAH4K9QT36u-KTZkE_dG-%3D79WWb%2BX08WA%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.