Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write any(s : SequenceType) in Swift

Tags:

swift

Swift doesn't seem to have functions for any() or all() so I am trying to make my own. The closest I have gotten is

func any<S: SequenceType
    where S.Generator.Element: BooleanType>
    (sequence: S) -> Bool{

    var __g = sequence.generate() 
    var first_element = __g.next()
    if first_element == nil{
        return false
    }
    return reduce(sequence, first_element!, {$0 || $1})
}

Edit: As per comments, this function should really look like this

func any<S: SequenceType
    where S.Generator.Element: BooleanType>
    (sequence: S) -> Bool{

    return reduce(sequence, false, {$0 || $1})
}

The compiler tells me

'S.Generator.Element' is not convertible to 'Bool'

It seems to me I am explicitly telling the compiler that it is on the second line. What am I missing?

like image 531
Hammer Avatar asked Aug 08 '14 03:08

Hammer


1 Answers

Your problem is that next returns an optional. That means reduce is expecting to return an optional and $0 is an optional. You would have to unwrap the optional to be able to use the || operator. You also don't know the the type is a Bool, just that it is a BooleanType. You would have to also convert it to an actual Bool by calling boolValue on it:

func any<S: SequenceType
    where S.Generator.Element: BooleanType>
    (sequence: S) -> Bool{

    var __g = sequence.generate() 
    var first_element = __g.next()
    if first_element == nil{
        return false
    }
    return reduce(sequence, first_element!.boolValue, {$0 || $1})
}

However, in this case, I think simplicity is best:

func any<S: SequenceType
    where S.Generator.Element: BooleanType>
    (sequence: S) -> Bool{

    for element in sequence {
        if element.boolValue {
            return true
        }
    }
    return false
}

This is actually more efficient too because it returns as soon as it finds the first true instead of always going through the whole thing.

like image 179
drewag Avatar answered Nov 15 '22 11:11

drewag