Skip to content

Instantly share code, notes, and snippets.

@brentsimmons
Created August 16, 2015 04:59
Show Gist options
  • Save brentsimmons/c794cb207aaeb1291348 to your computer and use it in GitHub Desktop.
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)
@devonc
Copy link

devonc 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
    }
}

@GuyEnglish
Copy link

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)

@masters3d
Copy link

//: 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

@natecook1000
Copy link

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.

@natecook1000
Copy link

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]
    }
}

@ryanbooker
Copy link

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)

@GuyEnglish
Copy link

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment