-
-
Save brentsimmons/c794cb207aaeb1291348 to your computer and use it in GitHub Desktop.
//: Playground - noun: a place where people can play | |
import Cocoa | |
var aSet = Set<Int>() | |
aSet.insert(1) | |
aSet.insert(2) | |
aSet.insert(3) | |
// The rest of this code doesn't even remotely work. | |
typealias TestBlock = (obj: AnyObject) -> Bool | |
extension Set { | |
func anyObjectPassingTest(testBlock: TestBlock) -> AnyObject? { | |
for oneObject in self { | |
if testBlock(oneObject) { | |
return oneObject | |
} | |
} | |
return nil | |
} | |
} | |
let x = aSet.anyObjectPassingTest { (obj) -> Bool in | |
return obj % 2 == 0 | |
} | |
print(x) |
Pearapps
commented
Aug 16, 2015
extension Set {
func anyObjectPassingTest(testBlock: (object: Element) -> Bool) -> Element? {
for oneObject in self where testBlock(object: oneObject) {
return oneObject
}
return nil
}
}
This will work:
extension Set {
func anyObjectPassingTest(testBlock: (Set.Element) -> Bool ) -> Set.Element? {
for oneObject in self {
if testBlock(oneObject) {
return oneObject
}
}
return nil
}
}
let x = aSet.anyObjectPassingTest { (obj) -> Bool in
return obj % 2 == 0
}
print(x)
//: Playground - noun: a place where people can play
import UIKit
var aSet = Set<Int>()
aSet.insert(1)
aSet.insert(2)
aSet.insert(3)
extension Set {
typealias TestBlock = (obj: Element) -> Bool
func anyObjectPassingTest(testBlock: TestBlock) -> Element? {
for oneObject in self {
if testBlock(obj: oneObject) {
return oneObject
}
}
return nil
}
}
var x = aSet.anyObjectPassingTest{ $0 % 2 == 0 }
print(x) // Optional(2)
// xcode 7 beta4
Guy English has the right answer, although you'd want an @noescape
in there, too—the signature should basically match the indexOf
method that's part of CollectionType.
Speaking of which, Set
is indexable, so you can alternately implement it this way:
extension Set {
func anyObjectPassingTest(@noescape test: (Element) -> Bool) -> Element? {
guard let index = self.indexOf(test) else { return nil }
return self[index]
}
}
extension Set {
func anyObjectPassingTest(@noescape p: Element -> Bool) -> Element? {
for e in self {
if p(e) return e
}
return nil
}
}
let s: Set<Int> = [1, 2, 3]
let x = s.anyObjectPassingTest { $0 % 2 == 0 }
print(x)
// Or just filter.
// Though this will work on the whole set and then grab the first.
// Is there a way to make it lazy?
let y = s.filter({$0 % 2 == 0}).first
print(y)
@natecook1000: The second solution is pretty nifty. Finds the first element. I assume it stops iterating the collection there. Then returns it. There's (from a casual understanding) an extra pointer deference there for the return self[index] but who cares and that's a nice way of expressing it. You're totally right that it should match the indexOf method. I'd missed @NoEscape at some point. DIdn't know that was a thing! Thanks.