Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objective-C code (array.indexOfObjectPassingTest) to Swift

How can I use the Objective-C code below in Swift, I tried but something is wrong.

Objective-C:

NSUInteger index = [theArray indexOfObjectPassingTest:
            ^BOOL(NSDictionary *dict, NSUInteger idx, BOOL *stop)
            {
                return [[dict objectForKey:@"name"] isEqual:theValue];
            }
    ];

Swift (Doesn't work):

let index = theArray.indexOfObjectPassingTest { (var dict: NSDictionary, var ind: Int, var bool: Bool) -> Bool in
                return dict.objectForKey("name")?.isEqual("theValue")
            }
like image 472
Geek20 Avatar asked Feb 10 '23 08:02

Geek20


1 Answers

I played with it and got this to work:

let theArray: NSArray = [["name": "theName"], ["name": "theStreet"], ["name": "theValue"]]

let index = theArray.indexOfObjectPassingTest { (dict, ind, bool) in return dict["name"] as? String == "theValue" }

if index == NSNotFound {
    print("not found")
} else {
    print(index)    // prints "2"
}

This can be further reduced. As @newacct mentioned in the comment, the return can be dropped since the closure is only a single line. Also, _ can be used in place of the parameters that aren't being used:

let index = theArray.indexOfObjectPassingTest { (dict, _, _) in dict["name"] as? String == "theValue" }

You can get rid of the parameter list in the closure entirely and use the default $0 value. Note in that case, the three parameters are combined as a tuple, so the first value of the tuple dict is referenced as $0.0:

let index = theArray.indexOfObjectPassingTest { $0.0["name"] as? String == "theValue" }
like image 63
vacawama Avatar answered Feb 20 '23 15:02

vacawama