the Reverend
the Reverend

Reputation: 12559

Extend CollectionType add indexOutOfRange function

I'm trying to add a function that tells me if an index is out of range in an array.

the startIndex and endIndex of CollectionType seem to be generic, so I'm trying to restrict the extension only when the index type is Int. This code does not compile:

extension CollectionType where Index.Type is Int {
    public func psoIndexOutOfRange(index: Index.Type) -> Bool{
        return index < self.startIndex || index > self.endIndex
    }
}

Is it possible? and what would be the correct way to add this.

Upvotes: 1

Views: 336

Answers (2)

Airspeed Velocity
Airspeed Velocity

Reputation: 40963

Personally I think this would be better as an extension to Range, rather than to CollectionType:

extension Range where T: Comparable {
    func contains(element: Generator.Element) -> Bool {
        return element >= startIndex && element < endIndex
    }
}

which you could call like so (indices returns the range from the collection’s start to end index):

[1,2,3].indices.contains(2)

Note, CollectionType (which Range conforms to) already has a contains method – but done via linear search. This overloads contains for ranges specifically to do it in constant time.

Also, if you're doing this in order to combine it with a subscript fetch, consider adding an optional fetch to make things easier:

extension CollectionType where Index: Comparable {
    subscript(safe idx: Index) -> Generator.Element? {
        guard indices.contains(idx) else { return nil }
        return self[idx]
    }
}

let a = [1,2,3]
a[safe: 4]  // nil

Upvotes: 3

ABakerSmith
ABakerSmith

Reputation: 22939

How about:

extension CollectionType where Index: Comparable {
    public func psoIndexOutOfRange(index: Index) -> Bool{
        return index < self.startIndex || index >= self.endIndex
    }
}

As @MartinR suggested, it's more general if you use Comparable instead of constraining Index to be of type Int.

Upvotes: 2

Related Questions