# I need the opposite of \`..\<index\`, why is there no \`index\>..\`?

**URL:** <https://forums.swift.org/t/i-need-the-opposite-of-index-why-is-there-no-index/48186>\
**Category:** Using Swift\
**Created:** [May 11, 2021, 6:05pm UTC](https://forums.swift.org/t/i-need-the-opposite-of-index-why-is-there-no-index/48186 "2021-05-11T18:05:37Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![young](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/young/32/7878_2.png) [@young](https://forums.swift.org/u/young)\
**Post date:** [May 11, 2021, 6:05pm UTC](https://forums.swift.org/t/i-need-the-opposite-of-index-why-is-there-no-index/48186/1 "2021-05-11T18:05:37Z")

</div>

I have `someIndex` position right before the suffix I'm look for. So I need to get suffix like this:

```swift
collection[someIndex>..]

```

but there is no such postfix operator. So I have to calculate the after:

```swift
collection[collection.index(after: someIndex)...]

```

Why no `index>..`? Is there anyway to write this postfix operator?

From the existing one:

[prefix static func ..\< (maximum: Self) -\> PartialRangeUpTo](https://developer.apple.com/documentation/swift/comparable/2892945)

I don't see how to create `>..` without access to the collection to calculate index position?

---

<div class="post-metadata">

**Author:** ![THV](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/thv/32/16893_2.png) [@THV](https://forums.swift.org/u/THV)\
**Post date:** [May 11, 2021, 6:27pm UTC](https://forums.swift.org/t/i-need-the-opposite-of-index-why-is-there-no-index/48186/2 "2021-05-11T18:27:51Z")

</div>

Can you use a one-sided range?

```swift
collection[index...].dropFirst()

```

If this works, you would just need to make sure you have an explicit end condition to get you out of the loop since this kind of range would go in infinitely.

Rather than deleting the comment, this was corrected per @Lantua's comment below.

---

<div class="post-metadata">

**Author:** ![Lantua](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/lantua/32/8868_2.png) [@Lantua](https://forums.swift.org/u/Lantua)\
**Post date:** [May 11, 2021, 6:29pm UTC](https://forums.swift.org/t/i-need-the-opposite-of-index-why-is-there-no-index/48186/4 "2021-05-11T18:29:50Z")

</div>

"Filling the gap" for range expression was pitched a few times before (you can search for Range Expression in #evolution), though I don't think much has come out of it.

FWIW, `<..` isn't a valid operator right now as dot-operator must begin with dot.

PS

You can also do

```swift
collection[index...].dropFirst()

```

---

<div class="post-metadata">

**Author:** ![Lantua](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/lantua/32/8868_2.png) [@Lantua](https://forums.swift.org/u/Lantua)\
**Post date:** [May 11, 2021, 6:36pm UTC](https://forums.swift.org/t/i-need-the-opposite-of-index-why-is-there-no-index/48186/5 "2021-05-11T18:36:16Z")

</div>

> [@THV](#):
>
> Can you use a one-sided range starting with index+1?

Please don't do this. That `index + 1` is a valid and in-bound index is a very strong and fragile guarantee that works only on `Array` and `ArraySlice`. If you so much as to do `.lazy.filter`, you'd already have a problem.

---

<div class="post-metadata">

**Author:** ![THV](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/thv/32/16893_2.png) [@THV](https://forums.swift.org/u/THV)\
**Post date:** [May 11, 2021, 6:40pm UTC](https://forums.swift.org/t/i-need-the-opposite-of-index-why-is-there-no-index/48186/6 "2021-05-11T18:40:05Z")

</div>

So you have to use the .dropFirst() method or set the index with an explicit assignment before using it in the range operation?

---

<div class="post-metadata">

**Author:** ![Lantua](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/lantua/32/8868_2.png) [@Lantua](https://forums.swift.org/u/Lantua)\
**Post date:** [May 11, 2021, 6:46pm UTC](https://forums.swift.org/t/i-need-the-opposite-of-index-why-is-there-no-index/48186/7 "2021-05-11T18:46:57Z")

</div>

Given that the OP doesn't tell us what kind of collections we're concerning, it's probably either that, or manipulating the index directly using `collection.index(after:)`, which is already mentioned in the question.

---

<div class="post-metadata">

**Author:** ![Lantua](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/lantua/32/8868_2.png) [@Lantua](https://forums.swift.org/u/Lantua)\
**Post date:** [May 11, 2021, 6:51pm UTC](https://forums.swift.org/t/i-need-the-opposite-of-index-why-is-there-no-index/48186/8 "2021-05-11T18:51:56Z")

</div>

With all that said, you can implement `RangeExpression` and add operator similar to `..<` yourself if you're not let down by the fact that it won't be `<..` or `>..`

---

<div class="post-metadata">

**Author:** ![young](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/young/32/7878_2.png) [@young](https://forums.swift.org/u/young)\
**Post date:** [May 11, 2021, 7:03pm UTC](https://forums.swift.org/t/i-need-the-opposite-of-index-why-is-there-no-index/48186/9 "2021-05-11T19:03:02Z")

</div>

> [@Lantua](#):
>
> Given that the OP doesn't tell us what kind of collections

It’s a `BidirectionalCollection`

---

<div class="post-metadata">

**Author:** ![wowbagger](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/wowbagger/32/13847_2.png) [@wowbagger](https://forums.swift.org/u/wowbagger)\
**Post date:** [May 11, 2021, 7:20pm UTC](https://forums.swift.org/t/i-need-the-opposite-of-index-why-is-there-no-index/48186/10 "2021-05-11T19:20:46Z")

</div>

> [@young](#):
>
> Why no `index>..` ? Is there anyway to write this postfix operator?

As @Lantua explained up-thread

> [@Lantua](#):
>
> `<..` isn't a valid operator right now as dot-operator must begin with dot.

And expanding on it a bit, this is because of the limit of [character combinations allowed](https://docs.swift.org/swift-book/ReferenceManual/LexicalStructure.html#ID418) in an operator for it to be parsed unambiguously.

If you need left-open right-closed intervals, I have an incomplete library [`Interval`](https://github.com/WowbaggersLiquidLunch/Interval) on GitHub. However, it has some significant [disadvantages](https://forums.swift.org/t/unify-and-expand-range-and-its-likes/38427/4) compared to `RangeExpression` types.

---

<div class="post-metadata">

**Author:** ![young](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/young/32/7878_2.png) [@young](https://forums.swift.org/u/young)\
**Post date:** [May 11, 2021, 9:24pm UTC](https://forums.swift.org/t/i-need-the-opposite-of-index-why-is-there-no-index/48186/12 "2021-05-11T21:24:19Z")

</div>

> [@Lantua](#):
>
> With all that said, you can implement `RangeExpression` and add operator similar to `..<` yourself if you're not let down by the fact that it won't be `<..` or `>..`

Not sure what `RangeExpression` mean here for defining an custom postfix operator to get partial range I want.

Anyway, I don't care what the operator is (a func is okay), only care for getting my suffix partial range without have access to the `Collection`. I give it a try:

```swift
postfix operator |||

extension Comparable {
    postfix static func ||| (minimum: Self) -> PartialRangeFrom<Self> where Self: Strideable, Self.Stride: SignedInteger {
        // only can do this
// minimum...
        // how to advance minimum to exclude the first position?
        (minimum...).dropFirst() // error: Referencing instance method 'dropFirst' on 'PartialRangeFrom' requires that 'Self' conform to 'Strideable'
        // ^^^ error: Cannot convert return expression of type 'DropFirstSequence<(PartialRangeFrom<Self>)>' to return type 'PartialRangeFrom<Self>'
    }
}

```

I failed ☹

---

<div class="post-metadata">

**Author:** ![Lantua](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/lantua/32/8868_2.png) [@Lantua](https://forums.swift.org/u/Lantua)\
**Post date:** [May 11, 2021, 9:44pm UTC](https://forums.swift.org/t/i-need-the-opposite-of-index-why-is-there-no-index/48186/13 "2021-05-11T21:44:16Z")

</div>

Ok, yea, `RangeExpression` documentation is a little obscure. Though much of it is a convention and not strict API rules/guarantees.

In any case, if you'd like the postfix operator to _feel_ like other range expressions, you're on the right track that `comparable|||` needs to return a new type that you implement. However, you also need to conform `PartialRangeFrom` to `RangeExpression`. That's where you'll get an opportunity to _remove the first item_, in `RangeExpression.relative(to:)`.

```swift
postfix operator |||

struct PartialRangeFrom<Bound: Comparable>: RangeExpression {
  var bound: Bound
    
  func contains(_ element: Bound) -> Bool { bound < element }
  func relative<C>(to collection: C) -> Range<Bound> where C : Collection, Self.Bound == C.Index {
    (collection.index(after: bound)...).relative(to: collection)
  }
}
extension Comparable {
  postfix static func |||(bound: Self) -> PartialRangeFrom<Self> {
    .init(bound: bound)
  } 
}

let a = [0, 1, 2]
a[a.startIndex|||] // [1, 2]

```

In this case though, don't forget to document that `bound` cannot be `endIndex`, since we're not handling that right now (you can if you'd like to).

---

<div class="post-metadata">

**Author:** ![young](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/young/32/7878_2.png) [@young](https://forums.swift.org/u/young)\
**Post date:** [May 12, 2021, 12:24am UTC](https://forums.swift.org/t/i-need-the-opposite-of-index-why-is-there-no-index/48186/14 "2021-05-12T00:24:20Z")

</div>

Thank you for showing how `RangeExpression` work.

So guessing at how things work, from something like this:

`someCollection[someRangeExpression]`

The compiler must be generating code that calls the `someRangeExpression.relative(to:)` passing in the `Collection` to get a `Range`. This answers my question of how an `index` can get a hold of a `Collection` to do index calculation.

> [@Lantua](#):
>
> `(collection.index(after: bound)...).relative(to: collection)`

that's very interesting that's calling `.relative(to:)` again...to convert a `PartialRangeFrom` to a `Range`...

---

<div class="post-metadata">

**Author:** ![Lantua](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/lantua/32/8868_2.png) [@Lantua](https://forums.swift.org/u/Lantua)\
**Post date:** [May 12, 2021, 2:22am UTC](https://forums.swift.org/t/i-need-the-opposite-of-index-why-is-there-no-index/48186/15 "2021-05-12T02:22:12Z")

</div>

> [@young](#):
>
> that's very interesting that's calling `.relative(to:)` again...

Welp, that's what 1-minute coding does to your program 😏. Can prolly just do

```swift
collection.index(after: bound)..<collection.endIndex

```

---

<div class="post-metadata">

**Author:** ![Lantua](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/lantua/32/8868_2.png) [@Lantua](https://forums.swift.org/u/Lantua)\
**Post date:** [May 12, 2021, 2:50am UTC](https://forums.swift.org/t/i-need-the-opposite-of-index-why-is-there-no-index/48186/16 "2021-05-12T02:50:26Z")

</div>

> [@young](#):
>
> The compiler must be generating code that calls the `someRangeExpression.relative(to:)` passing in the `Collection` to get a `Range` .

Also, yes.

> <https://github.com/apple/swift/blob/93eae81b0485507ea982440cc6968a4d94252999/stdlib/public/core/Range.swift#L930>

---

<div class="post-metadata">

**Author:** ![young](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/young/32/7878_2.png) [@young](https://forums.swift.org/u/young)\
**Post date:** [May 12, 2021, 11:29pm UTC](https://forums.swift.org/t/i-need-the-opposite-of-index-why-is-there-no-index/48186/17 "2021-05-12T23:29:30Z")

</div>

> [@Lantua](#):
>
> `PartialRangeFrom`

How come you can redefine `PartialRangeFrom` and not have conflict with [the built-in one](https://github.com/apple/swift/blob/93eae81b0485507ea982440cc6968a4d94252999/stdlib/public/core/Range.swift#L652)?

---

<div class="post-metadata">

**Author:** ![cukr](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/cukr/32/889_2.png) [@cukr](https://forums.swift.org/u/cukr)\
**Post date:** [May 12, 2021, 11:52pm UTC](https://forums.swift.org/t/i-need-the-opposite-of-index-why-is-there-no-index/48186/18 "2021-05-12T23:52:58Z")

</div>

Things defined in the current module are prioritised over things defined in other modules. That way people can add things to libraries without worrying about breaking source stability too much. It's similar to how variables in inner scopes can shadow the ones in outer scopes. If you want to use the one from standard library, you can still write `Swift.PartialRangeFrom`
