Saltymule
Saltymule

Reputation: 2937

How to compare nested collections in swift

I have two collections:

let collection1:[String:[String:NSObject]] = ["somekey":["nestedkey":"value"]]

let collection2:[String:[String:NSObject]] = ["somekey":["nestedkey":"value"]]

//I would like to compare them using the following:

let collectionsAreEqual = collection1 == collection2

Copying and pasting the above code into a playground gives the following error:

enter image description here

I know I can write an equal function for this:

infix func == (this:[String:[String:NSObject]], that:[String:[String:NSObject]]){
    //return true or false
}

In objective c, isEqual: on an NSDictionary handles this no problem, because it does the nested comparison for you. Is there some method of generally handling this in swift?

Update

I can use the following:

//:[String:[String:NSObject]]
let collection1:[String:NSObject] = ["somekey":["nestedkey":"value"]]

let collection2:[String:NSObject] = ["somekey":["nestedkey":"value"]]
//I would like to compare them using the following:

let collectionsAreEqual = collection1 == collection2

but it requires using NSObject as the value in the declaration. Is there a pure swift method to handle this?

Upvotes: 9

Views: 4097

Answers (2)

A.Rennertz
A.Rennertz

Reputation: 1

try this:

let collection1:[String:NSObject] = ["somekey":["nestedkey":"value"]]

let collection2:[String:NSObject] = ["somekey":["nestedkey":"value"]]

let collectionsAreEqual = ((collection1 as NSDictionary).isEqual(collection2 as NSDictionary)

By casting the swift objects to Foundation objects they get the equality operator. They will call the equality operator on every element recursively, so there you have your deep comparison.

Upvotes: 0

Nate Cook
Nate Cook

Reputation: 93276

Here's an equality operator that will compare any two nested dictionaries with the same type:

func ==<T: Equatable, K1: Hashable, K2: Hashable>(lhs: [K1: [K2: T]], rhs: [K1: [K2: T]]) -> Bool {
    if lhs.count != rhs.count { return false }

    for (key, lhsub) in lhs {
        if let rhsub = rhs[key] {
            if lhsub != rhsub {
                return false
            }
        } else {
            return false
        }
    }

    return true
}

Upvotes: 14

Related Questions