0

The goal of this code below is to filter out dictionaries with a certain ID, where ID is a string.

    let dictArray = networkData["dicts"] as! [[String:AnyObject]]
    localData["dicts"] = dictArray.filter{ ($0["id"] as! String) != sample.getId() }

This code, however, generates an error:

Cannot invoke 'filter' with an argument list of type '(([String : AnyObject]) throws -> Bool)'

Based on other SO answers like this one and this one, it seems the error is the dictionaries don't conform to Equatable.

So is the only option for using filter to create a custom class to hold the array of dictionaries and make that class conform to Equatable?

If so, perhaps it seems cleaner to simply iterate and create a new array.

19
  • What are hash objects? Commented Jan 3, 2017 at 2:57
  • Please make sure you define filteredData: [String: [[String: AnyObject]]] Commented Jan 3, 2017 at 3:04
  • @Alexander He probably means dictionaries Commented Jan 3, 2017 at 3:09
  • @matt That's what I suspected, but he's not comparing equality of dictionaries anywhere Commented Jan 3, 2017 at 3:11
  • I would suggest that declare let id = sample.getId() out of the filter block and use the id instead of. Commented Jan 3, 2017 at 3:16

2 Answers 2

2

Filtering [[String:AnyObject]] (a.k.a. Array>) results in another [[String:AnyObject]]. You're trying to assign this to a var of type AnyObject, which is not allowed in Swift 3, since arrays are structs, not objects.

Make a type-safe struct or object to hold this data, rather than a dict.

For example:

let dictArray = networkData["dicts"] as! [[String:AnyObject]]
let filteredDicts = dictArray.filter{ ($0["id"] as! String) != sample.getId() }         
localData["dicts"] = filteredDicts
Sign up to request clarification or add additional context in comments.

7 Comments

thanks! but to be precise we're assigning the array of dictionaries to a var of type AnyObject (which also does not work in swift).
@Crashalot Good point. You can augment my answer. Please accept it if it helped
already upvoted. only haven't accepted because still need to fix the code. :) don't worry you will get the points if this leads to the solution. :)
btw any insight as to why this worked in swift 2.x and not swift 3.x? would also be valuable commentary.
Swift 2 allowed implicit bridging to Foundation types, such as from Array to NSArray (which is a class). This bridging has been made explicit in Swift 3, to lessen the dependence on Foundation types.
|
1

The issue isn't on hash objects not conform to Equatable because you are using String to do the comparing.

I have the code runs well in Playground:

// make sure data is type of [String: [[String: AnyObject]]]
// make sure filteredData is type of [String: [[String: AnyObject]]]

let key = "hashes"
if let hashArray = data[key] {
    let id = sample.getId() // make sure it's String type
    filteredData[key] = hashArray.filter { ($0["id"] as? String) != id }
}

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.