<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Swift used to do this, but we switched it around so indexes couldn’t self-increment.<div class=""><br class=""></div><div class=""><div>One of the problems was that strings are value-types. So you would get an index, then append stuff to the string, but when you tried to advance the index again it would blow up. The index retained the backing, which means the “append” caused a copy, and the index was suddenly pointing to a different String backing.</div><div><br class=""></div><div>Basically, self-incrementing indexes require that the Collection has reference semantics. Otherwise there simply is no concept of an independent “owning” Collection which your Index can hold a reference to.</div><div><br class=""></div><div>Anyway, that doesn’t mean you’re wrong. Collection-slicing syntax is still way too ugly. We need to keep it safe, and communicative, but it should also be obvious and not tiring.</div><div><br class=""></div><div>Currently, you have to write:</div><div><br class=""></div></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><div><font face="Courier" class=""><collection>[<collection>.index(<collection>.<member>, offsetBy: <distance>)]</font></div></div><div><font face="Courier" class=""><br class=""></font></div></blockquote>And an example...<br class=""><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div><font face="Courier" class=""><br class=""></font></div><div><font face="Courier" class="">results[results.index(results.startIndex, offsetBy: 3)]</font></div></blockquote><div class=""><div><br class=""></div><div>Which is safe, and communicative, and obvious, but also really, really tiring. There are ways we can make it less tiring without sacrificing the good parts:</div><div><br class=""></div><div>1) Add a version of index(_: offsetBy:) which takes a KeyPath<Self, Self.Index> as its first argument. That’s a minor convenience you can add today in your own projects. It removes one repetition of <collection>, in many common cases.</div></div><div><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div><font face="Courier" class="">extension Collection {</font></div><div><font face="Courier" class=""> func index(_ i: KeyPath<Self, Index>, offsetBy n: IndexDistance) -> Index {</font></div><div><font face="Courier" class=""> return index(self[keyPath: i], offsetBy: n)</font></div><div><font face="Courier" class=""> }</font></div><div><font face="Courier" class=""> func index(_ i: KeyPath<Self, Index>, offsetBy n: IndexDistance, limitedBy: Index) -> Index? {</font></div><div><font face="Courier" class=""> return index(self[keyPath: i], offsetBy: n, limitedBy: limitedBy)</font></div><div><font face="Courier" class=""> }</font></div><div><font face="Courier" class="">}</font></div></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div><br class=""></div></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><div><font face="Courier" class="">results[results.index(\.startIndex, offsetBy: 3)]</font></div></div><div><font face="Courier" class=""><br class=""></font></div></blockquote>Seriously, man, KeyPaths are just <i class="">the business</i>. I love them.<br class=""><div class=""><div><br class=""></div><div>2) Bind <collection> to something like an anonymous closure argument within the subscript. Or just allow “.” syntax, as for static members. That removes another <collection>.</div><div><br class=""></div></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div><span style="font-family: Courier;" class="">results[.index(\.startIndex, offsetBy: 3)]</span></div><div><span style="font-family: Courier;" class=""><br class=""></span></div><div><span style="font-family: Courier;" class="">or</span></div><div><span style="font-family: Courier;" class=""><br class=""></span></div><div><span style="font-family: Courier;" class="">results[$.index(\.startIndex, offsetBy: 3)]</span></div></blockquote><div><br class=""></div><div>If anybody’s interested, I was playing around with an “IndexExpression” type for this kind of thing. The language lets you get pretty far, but it doesn’t work and I can’t figure out why. It looks like a simple-enough generic struct, but it fails with a cyclic metadata dependency.</div><div><br class=""></div><div><a href="https://gist.github.com/karwa/04cc43431951f24ae9334ba8a25e6a31" class="">https://gist.github.com/karwa/04cc43431951f24ae9334ba8a25e6a31</a></div><div><br class=""></div><div>- Karl</div><div><br class=""></div><div class=""><div><blockquote type="cite" class=""><div class="">On 19. Dec 2017, at 08:38, Cao, Jiannan via swift-dev <<a href="mailto:swift-dev@swift.org" class="">swift-dev@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html; charset=gb2312" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><meta http-equiv="Content-Type" content="text/html; charset=gb2312" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div class="">I implemented the second approach: SuperIndex</div><div class=""><br class=""></div><a href="https://github.com/frogcjn/SuperStringIndex/" class="">https://github.com/frogcjn/SuperStringIndex/</a><div class=""><br class=""></div><div class=""><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(36, 41, 46); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; font-size: 16px; background-color: rgb(255, 255, 255);" class="">SuperString is a special version of String. Its SuperIndex keeps a reference to the string, let the index calculate the offset.</p><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(112, 61, 170); background-color: rgb(255, 255, 255);" class=""><span style="color: #ba2da2" class="">struct</span><span style="font-stretch: normal; line-height: normal; font-family: "Fira Code";" class=""> SuperIndex : </span>Comparable<span style="font-stretch: normal; line-height: normal; font-family: "Fira Code";" class="">, </span>Strideable<span style="font-stretch: normal; line-height: normal; font-family: "Fira Code";" class="">, </span>CustomStringConvertible<span style="font-stretch: normal; line-height: normal; font-family: "Fira Code";" class=""> {</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: "Fira Code"; background-color: rgb(255, 255, 255); min-height: 13px;" class=""> <br class="webkit-block-placeholder"></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: "Fira Code"; background-color: rgb(255, 255, 255);" class=""> <span style="font-stretch: normal; line-height: normal; font-family: Menlo; color: rgb(186, 45, 162);" class="">var</span> owner: <span style="font-stretch: normal; line-height: normal; font-family: Menlo; color: rgb(112, 61, 170);" class="">Substring</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: "Fira Code"; background-color: rgb(255, 255, 255);" class=""> <span style="font-stretch: normal; line-height: normal; font-family: Menlo; color: rgb(186, 45, 162);" class="">var</span> wrapped: <span style="font-stretch: normal; line-height: normal; font-family: Menlo; color: rgb(112, 61, 170);" class="">String</span>.<span style="font-stretch: normal; line-height: normal; font-family: Menlo; color: rgb(112, 61, 170);" class="">Index</span></div><p style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: "Fira Code"; background-color: rgb(255, 255, 255); min-height: 13px;" class=""> <br class="webkit-block-placeholder"></p><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>...</div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: "Fira Code"; background-color: rgb(255, 255, 255); min-height: 13px;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0); background-color: rgb(255, 255, 255);" class=""><span style="font-stretch: normal; line-height: normal; font-family: "Fira Code";" class=""> </span>// Offset</div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: "Fira Code"; background-color: rgb(255, 255, 255);" class=""> <span style="font-stretch: normal; line-height: normal; font-family: Menlo; color: rgb(186, 45, 162);" class="">var</span> offset: <span style="font-stretch: normal; line-height: normal; font-family: Menlo; color: rgb(112, 61, 170);" class="">Int</span> {</div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="font-stretch: normal; line-height: normal; font-family: "Fira Code";" class=""> </span><span style="color: #ba2da2" class="">return</span><span style="font-stretch: normal; line-height: normal; font-family: "Fira Code";" class=""> </span><span style="color: #4f8187" class="">owner</span><span style="font-stretch: normal; line-height: normal; font-family: "Fira Code";" class="">.</span><span style="color: #3e1e81" class="">distance</span><span style="font-stretch: normal; line-height: normal; font-family: "Fira Code";" class="">(from: </span><span style="color: #4f8187" class="">owner</span><span style="font-stretch: normal; line-height: normal; font-family: "Fira Code";" class="">.</span><span style="color: #703daa" class="">startIndex</span><span style="font-stretch: normal; line-height: normal; font-family: "Fira Code";" class="">, to: </span><span style="color: #4f8187" class="">wrapped</span><span style="font-stretch: normal; line-height: normal; font-family: "Fira Code";" class="">)</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: "Fira Code"; background-color: rgb(255, 255, 255);" class=""> }</div></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: "Fira Code"; background-color: rgb(255, 255, 255);" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: "Fira Code"; background-color: rgb(255, 255, 255);" class=""> // <span style="color: rgb(112, 61, 170); font-family: Menlo;" class="">Strideable</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: "Fira Code"; background-color: rgb(255, 255, 255);" class=""><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo;" class=""><span style="font-stretch: normal; line-height: normal; font-family: "Fira Code";" class=""> </span><span style="color: #ba2da2" class="">func</span><span style="font-stretch: normal; line-height: normal; font-family: "Fira Code";" class=""> advanced(by n: </span><span style="color: #4f8187" class="">SuperIndex</span><span style="font-stretch: normal; line-height: normal; font-family: "Fira Code";" class="">.</span><span style="color: #4f8187" class="">Stride</span><span style="font-stretch: normal; line-height: normal; font-family: "Fira Code";" class="">) -> </span><span style="color: #4f8187" class="">SuperIndex</span><span style="font-stretch: normal; line-height: normal; font-family: "Fira Code";" class=""> {</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo;" class=""><span style="font-stretch: normal; line-height: normal; font-family: "Fira Code";" class=""> </span><span style="color: #ba2da2" class="">return</span><span style="font-stretch: normal; line-height: normal; font-family: "Fira Code";" class=""> </span><span style="color: #4f8187" class="">SuperIndex</span><span style="font-stretch: normal; line-height: normal; font-family: "Fira Code";" class="">(</span><span style="color: #4f8187" class="">owner</span><span style="font-stretch: normal; line-height: normal; font-family: "Fira Code";" class="">.</span><span style="color: #3e1e81" class="">index</span><span style="font-stretch: normal; line-height: normal; font-family: "Fira Code";" class="">(</span><span style="color: #4f8187" class="">wrapped</span><span style="font-stretch: normal; line-height: normal; font-family: "Fira Code";" class="">, offsetBy: n), </span><span style="color: #4f8187" class="">owner</span><span style="font-stretch: normal; line-height: normal; font-family: "Fira Code";" class="">)</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""> }</div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135);" class=""><span style="font-stretch: normal; line-height: normal; font-family: "Fira Code";" class=""> </span><span style="color: #ba2da2" class="">static</span><span style="font-stretch: normal; line-height: normal; font-family: "Fira Code";" class=""> </span><span style="color: #ba2da2" class="">func</span><span style="font-stretch: normal; line-height: normal; font-family: "Fira Code";" class=""> +(lhs: </span>SuperIndex<span style="font-stretch: normal; line-height: normal; font-family: "Fira Code";" class="">, rhs: </span>SuperIndex<span style="font-stretch: normal; line-height: normal; font-family: "Fira Code";" class="">.</span>Stride<span style="font-stretch: normal; line-height: normal; font-family: "Fira Code";" class="">) -> </span>SuperIndex<span style="font-stretch: normal; line-height: normal; font-family: "Fira Code";" class=""> {</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""> <span style="font-stretch: normal; line-height: normal; font-family: Menlo; color: rgb(186, 45, 162);" class="">return</span> lhs.<span style="font-stretch: normal; line-height: normal; font-family: Menlo; color: rgb(49, 89, 93);" class="">advanced</span>(by: rhs)</div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""> }</div></div></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: "Fira Code"; background-color: rgb(255, 255, 255);" class="">}</div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: "Fira Code"; background-color: rgb(255, 255, 255);" class=""><br class=""></div><div class="highlight highlight-source-swift" style="box-sizing: border-box; margin-bottom: 16px; color: rgb(36, 41, 46); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; font-size: 16px; background-color: rgb(255, 255, 255);"><pre style="box-sizing: border-box; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.600000381469727px; margin-top: 0px; margin-bottom: 0px; word-wrap: normal; padding: 16px; overflow: auto; line-height: 1.45; background-color: rgb(246, 248, 250); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: normal;" class=""><span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">let</span> a<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">:</span> SuperString <span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">=</span> <span class="pl-s" style="box-sizing: border-box; color: rgb(3, 47, 98);"><span class="pl-pds" style="box-sizing: border-box;">"</span>01234<span class="pl-pds" style="box-sizing: border-box;">"</span></span>
<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">let</span> o <span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">=</span> a.<span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">startIndex</span>
<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">let</span> o1 <span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">=</span> o <span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">+</span> <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">4</span>
<span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">print</span>(a[o]) <span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"><span class="pl-c" style="box-sizing: border-box;">//</span> 0</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"></span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">print</span>(a[<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">...</span>]) <span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"><span class="pl-c" style="box-sizing: border-box;">//</span> 01234</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"></span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">print</span>(a[<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">..<</span>(o<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">+</span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">2</span>)]) <span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"><span class="pl-c" style="box-sizing: border-box;">//</span> 01</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"></span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">print</span>(a[<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">...</span>(o<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">+</span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">2</span>)]) <span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"><span class="pl-c" style="box-sizing: border-box;">//</span> 012</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"></span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">print</span>(a[(o<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">+</span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">2</span>)<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">...</span>]) <span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"><span class="pl-c" style="box-sizing: border-box;">//</span> 234</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"></span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">print</span>(a[o<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">+</span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">2</span><span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">..<</span>o<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">+</span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">3</span>]) <span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"><span class="pl-c" style="box-sizing: border-box;">//</span> 2</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"></span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">print</span>(a[o1<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">-</span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">2</span><span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">...</span><span class="pl-smi" style="box-sizing: border-box;">o1</span><span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">-</span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">1</span>]) <span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"><span class="pl-c" style="box-sizing: border-box;">//</span> 23</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"></span>
<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">if</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">let</span> number <span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">=</span> a.<span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">index</span>(<span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">of</span>: <span class="pl-s" style="box-sizing: border-box; color: rgb(3, 47, 98);"><span class="pl-pds" style="box-sizing: border-box;">"</span>1<span class="pl-pds" style="box-sizing: border-box;">"</span></span>) {
<span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">print</span>(number) <span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"><span class="pl-c" style="box-sizing: border-box;">//</span> 1</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"></span> <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">print</span>(a[number<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">...</span>]) <span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"><span class="pl-c" style="box-sizing: border-box;">//</span> 1234</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"></span>}
<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">if</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">let</span> number <span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">=</span> a.<span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">index</span>(<span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">where</span>: { <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">$0</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">></span> <span class="pl-s" style="box-sizing: border-box; color: rgb(3, 47, 98);"><span class="pl-pds" style="box-sizing: border-box;">"</span>1<span class="pl-pds" style="box-sizing: border-box;">"</span></span> }) {
<span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">print</span>(number) <span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"><span class="pl-c" style="box-sizing: border-box;">//</span> 2</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"></span>}
<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">let</span> b <span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">=</span> a[(o<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">+</span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">1</span>)<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">...</span>]
<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">let</span> z <span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">=</span> b.<span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">startIndex</span>
<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">let</span> z1 <span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">=</span> z <span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">+</span> <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">4</span>
<span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">print</span>(b[z]) <span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"><span class="pl-c" style="box-sizing: border-box;">//</span> 1</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"></span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">print</span>(b[<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">...</span>]) <span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"><span class="pl-c" style="box-sizing: border-box;">//</span> 1234</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"></span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">print</span>(b[<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">..<</span>(z<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">+</span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">2</span>)]) <span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"><span class="pl-c" style="box-sizing: border-box;">//</span> 12</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"></span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">print</span>(b[<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">...</span>(z<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">+</span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">2</span>)]) <span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"><span class="pl-c" style="box-sizing: border-box;">//</span> 123</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"></span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">print</span>(b[(z<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">+</span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">2</span>)<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">...</span>]) <span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"><span class="pl-c" style="box-sizing: border-box;">//</span> 34</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"></span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">print</span>(b[z<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">+</span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">2</span><span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">...</span><span class="pl-smi" style="box-sizing: border-box;">z</span><span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">+</span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">3</span>]) <span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"><span class="pl-c" style="box-sizing: border-box;">//</span> 34</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"></span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">print</span>(b[z1<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">-</span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">2</span><span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">...</span><span class="pl-smi" style="box-sizing: border-box;">z1</span><span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">-</span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">2</span>]) <span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"><span class="pl-c" style="box-sizing: border-box;">//</span> 3</span></pre></div><div class=""><br class=""></div><div class=""><br class=""><blockquote type="cite" class=""><div class="">在 2017年12月18日,下午4:53,Cao, Jiannan <<a href="mailto:frogcjn@163.com" class="">frogcjn@163.com</a>> 写道:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html; charset=gb2312" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><meta http-equiv="Content-Type" content="text/html; charset=gb2312" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><meta http-equiv="Content-Type" content="text/html; charset=gb2312" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Or we can copy the design of std::vector::iterator in C++.The index could keep a reference to the collection.<div class="">When the index being offset by + operator, it could call the owner to offset the index, since it keeps a reference to the collection owner.<br class=""><div class=""><br class=""></div><div class="">let startIndex = s.startIndex</div><div class="">s[startIndex+1]</div><div class=""><br class=""></div></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><div style="margin: 0px; font-stretch: normal; line-height: normal; color: rgb(112, 61, 170);" class=""><span style="color: #ba2da2" class="">public</span><span style="font-stretch: normal; line-height: normal; font-family: "Fira Code";" class=""> </span><span style="color: #ba2da2" class="">struct</span><span style="font-stretch: normal; line-height: normal; font-family: "Fira Code";" class=""> MyIndex<T: </span>Collection<span style="font-stretch: normal; line-height: normal; font-family: "Fira Code";" class="">> : </span>Comparable<span style="font-stretch: normal; line-height: normal; font-family: "Fira Code";" class=""> </span><span style="color: #ba2da2" class="">where</span><span style="font-stretch: normal; line-height: normal; font-family: "Fira Code";" class=""> </span>T<span style="font-stretch: normal; line-height: normal; font-family: "Fira Code";" class="">.</span>Index<span style="font-stretch: normal; line-height: normal; font-family: "Fira Code";" class=""> == </span>MyIndex<span style="font-stretch: normal; line-height: normal; font-family: "Fira Code";" class=""> {</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Fira Code";" class=""> <span style="font-stretch: normal; line-height: normal; font-family: Menlo; color: rgb(186, 45, 162);" class="">public</span> <span style="font-stretch: normal; line-height: normal; font-family: Menlo; color: rgb(186, 45, 162);" class="">let</span> owner: <span style="font-stretch: normal; line-height: normal; font-family: Menlo; color: rgb(112, 61, 170);" class="">T</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Fira Code";" class=""><span style="font-stretch: normal; line-height: normal; font-family: Menlo; color: rgb(112, 61, 170);" class="">...</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><span style="font-stretch: normal; line-height: normal; font-family: "Fira Code";" class=""> </span><span style="color: #ba2da2" class="">public</span><span style="font-stretch: normal; line-height: normal; font-family: "Fira Code";" class=""> </span><span style="color: #ba2da2" class="">static</span><span style="font-stretch: normal; line-height: normal; font-family: "Fira Code";" class=""> </span><span style="color: #ba2da2" class="">func</span><span style="font-stretch: normal; line-height: normal; font-family: "Fira Code";" class=""> + (lhs: </span><span style="color: #703daa" class="">MyIndex</span><span style="font-stretch: normal; line-height: normal; font-family: "Fira Code";" class="">, rhs: </span><span style="color: #703daa" class="">T</span><span style="font-stretch: normal; line-height: normal; font-family: "Fira Code";" class="">.</span><span style="color: #703daa" class="">IndexDistance</span><span style="font-stretch: normal; line-height: normal; font-family: "Fira Code";" class="">) -> </span><span style="color: #703daa" class="">MyIndex</span><span style="font-stretch: normal; line-height: normal; font-family: "Fira Code";" class=""> {</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Fira Code";" class=""> <span style="font-stretch: normal; line-height: normal; font-family: Menlo; color: rgb(186, 45, 162);" class="">return</span> lhs.owner.index(lhs, offsetBy: rhs)</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Fira Code";" class=""> }</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Fira Code";" class="">}</div></div></div></blockquote><div class=""><div class=""><div class=""><br class=""><blockquote type="cite" class=""><div class="">在 2017年12月15日,上午9:34,Michael Ilseman <<a href="mailto:milseman@apple.com" class="">milseman@apple.com</a>> 写道:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html; charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Yes, I was trying to highlight that they are different and should be treated different. This was because it seemed you were conflating the two in your argument. You claim that people expect it, and I’m pointing out that what people actually expect (assuming they’re coming from C or languages with a similar model) already exists as those models deal in encoded offsets.<div class=""><br class=""></div><div class="">More important than expectations surrounding what to provide to a subscript are expectations surrounding algorithmic complexity. This has security implications. The expectation of subscript is that it is “constant-ish”, for a fuzzy hand-wavy definition of “constant-ish” which includes amortized constant or logarithmic.</div><div class=""><br class=""></div><div class="">Now, I agree with the overall sentiment that `index(offsetBy:)` is unwieldy. I am interested in approaches to improve this. But, we cannot throw linear complexity into subscript without extreme justification.</div><div class=""><br class=""><div class=""><br class=""><blockquote type="cite" class=""><div class="">On Dec 14, 2017, at 5:25 PM, Cao, Jiannan <<a href="mailto:frogcjn@163.com" class="">frogcjn@163.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html; charset=gb2312" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><meta http-equiv="Content-Type" content="text/html; charset=gb2312" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">This offset is unicode offset, is not the offset of element. <div class="">For example: index(startIndex, offsetBy:1) is encodedOffset 4 or 8, not 1.</div><div class=""><br class=""></div><div class="">Offset indexable is based on the offset of count of each element/index. it is the same result of s.index(s.startIndex, offsetBy:i)</div><div class="">The encodedOffset is the underlaying offset of unicode string, not the same concept of the offset index of collection.</div><div class=""><br class=""></div><div class="">The offset indexable is meaning to the elements and index of collection (i-th element of the collection), not related to the unicode offset (which is the underlaying data offset meaning to the UTF-16 String).</div><div class=""><br class=""></div><div class="">These two offset is totally different.</div><div class=""><div class=""><br class=""></div><div class="">Best,</div><div class="">Jiannan</div><div class=""><br class=""><blockquote type="cite" class=""><div class="">在 2017年12月15日,上午9:17,Michael Ilseman <<a href="mailto:milseman@apple.com" class="">milseman@apple.com</a>> 写道:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html; charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><br class=""><div class=""><br class=""><blockquote type="cite" class=""><div class="">On Dec 14, 2017, at 4:49 PM, Cao, Jiannan via swift-dev <<a href="mailto:swift-dev@swift.org" class="">swift-dev@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html; charset=gb2312" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><meta http-equiv="Content-Type" content="text/html; charset=gb2312" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div class="">People used to the offset index system instead of the String.Index. Using offset indices to name the elements, count the elements is normal and nature.</div><div class=""><br class=""></div></div></div></div></blockquote><div class=""><br class=""></div><div class="">The offset system that you’re referring to is totally available in String today, if you’re willing for it to be the offset into the encoding. That’s the offset “people” you’re referring to are likely used to and consider normal and natural. On String.Index, there is the following:</div><div class=""><br class=""></div><div class=""><pre class="code-source code-source-indented" data-language="swift" style="box-sizing: inherit; margin-top: 0px; margin-bottom: 0px; padding: 0.35294rem 0.58824rem 0.35294rem 2.47059em; font-size: 17px; white-space: normal; overflow-wrap: normal; word-wrap: normal; letter-spacing: 0px; overflow: auto; background-color: rgb(249, 250, 250); border: 1px solid rgb(230, 230, 230); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; speak: literal-punctuation; text-indent: -1.88235em; color: rgb(51, 51, 51);"><code style="box-sizing: inherit; font-size: 15px; font-family: "SF Mono", Menlo, monospace, "SF Pro Icons"; letter-spacing: -0.027em; line-height: 1.26667;" class=""><span class="syntax-keyword" style="box-sizing: inherit; color: rgb(170, 13, 145);">init</span>(<span class="syntax-identifier" style="box-sizing: inherit;">encodedOffset</span> <span class="syntax-param-name" style="box-sizing: inherit; color: rgb(64, 64, 64);">offset</span>: <a class="symbolref" href="https://developer.apple.com/documentation/swift/int" style="box-sizing: inherit; color: rgb(92, 38, 153); text-decoration: none;">Int</a>)</code></pre><div class=""><br class=""></div><div class="">and </div><div class=""><br class=""></div><div class=""><pre class="code-source code-source-indented" data-language="swift" style="box-sizing: inherit; margin-top: 0px; margin-bottom: 0px; padding: 0.35294rem 0.58824rem 0.35294rem 2.47059em; font-size: 17px; white-space: normal; overflow-wrap: normal; word-wrap: normal; letter-spacing: 0px; overflow: auto; background-color: rgb(249, 250, 250); border: 1px solid rgb(230, 230, 230); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; speak: literal-punctuation; text-indent: -1.88235em; color: rgb(51, 51, 51);"><code style="box-sizing: inherit; font-size: 15px; font-family: "SF Mono", Menlo, monospace, "SF Pro Icons"; letter-spacing: -0.027em; line-height: 1.26667;" class=""><span class="syntax-keyword" style="box-sizing: inherit; color: rgb(170, 13, 145);">var</span> <span class="syntax-identifier" style="box-sizing: inherit;">encodedOffset</span>: <a class="symbolref" href="https://developer.apple.com/documentation/swift/int" style="box-sizing: inherit; color: rgb(92, 38, 153); text-decoration: none;">Int</a> { <span class="syntax-keyword" style="box-sizing: inherit; color: rgb(170, 13, 145);">get</span> }</code></pre><div class=""><br class=""></div></div></div><div class=""><br class=""></div><div class="">[1] <a href="https://developer.apple.com/documentation/swift/string.index" class="">https://developer.apple.com/documentation/swift/string.index</a></div><div class=""><br class=""></div><div class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div class=""><div class=""><b class="">This offset index system has a long history and a real meaning to the collection. </b>The subscript s[i] has a fix meaning of "getting the i-th element in this collection", which is normal and direct. Get the range with offset indices, is also direct. It means the substring is from the i-th character up to the j-th character of the original string.</div><div class=""><br class=""></div></div><div class=""><div class="">People used to play subscript, range with offset indices. Use string[string.index(i, offsetBy: 5)] is not as directly and easily as string[i + 5]. Also the Range<String.Index> is not as directly as Range<Offset>. Developers need to transfer the Range<String.Index> result of string.range(of:) to Range<OffsetIndex> to know the exact range of the substring. Range<String.Index> has a real meaning to the machine and underlaying data location for the substring, but Range<OffsetIndex> also has a direct location information for human being, and represents<b class=""> the abstract location concept of the collection (This is the most UNIMPEACHABLE REASON I could provide)</b>.</div><div class=""><b class=""><br class=""></b></div><div class=""><b class="">Offset index system is based on the nature of collection. Each element of the collection could be located by offset, which is a direct and simple conception to any collection. Right? </b>Even the String with String.Index has some offset index property within it. For example: the `count` of the String, is the offset index of the endIndex.The enumerated() generated a sequence with elements contains the same offset as the offset index system provided. And when we apply Array(string), the string divided by each character and make the offset indices available for the new array.</div></div><div class=""><div class=""><br class=""></div><div class=""><b class="">The offset index system is just an assistant for collection, not a replacement to String.Index. </b>We use String.Index to represent the normal underlaying of the String. We also could use offset indices to represent the nature of the Collection with its elements. Providing the offset index as a second choice to access elements in collections, is not only for the String struct, is for all collections, since <b class="">it is the nature of the collection concept</b>, and developer could choose use it or not.<b class=""> </b><br class=""><br class=""></div><div class="">We don't make the String.Index O(1), but translate the offset indices to the underlaying String.Index. Each time using subscript with offset index, we just need to translate offset indices to underlaying indices using c.index(startIndex, offsetBy:i), c.distance(from: startIndex, to:i) </div></div><div class=""><br class=""></div><div class="">We can make the offset indices available through extension to Collection (as my GitHub repo demo: <a href="https://github.com/frogcjn/OffsetIndexableCollection-String-Int-Indexable-" class="" style="background-color: rgb(255, 255, 255);">https://github.com/frogcjn/OffsetIndexableCollection-String-Int-Indexable-</a>).</div><div class=""><br class=""></div>or we could make it at compile time:<div class="">for example</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>c[1...]</div><div class="">compile to</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>c[c.index(startIndex, offsetBy:1)...]</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>let index: Int = s.index(of: "a")</div><div class="">compile to</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>let index: Int = s.distance(from: s.startIndex, to: s.index(of:"a"))</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>let index = 1 // if used in s only</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>s[index..<index+2]</div><div class="">compile to</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>let index = s.index(s.startIndex, offsetBy: 1)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>s[index..<s.index(index, offsetBy: 2)]</div><div class=""><br class=""></div><div class=""><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>let index = 1 // if used both in s1, s2</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>s1[index..<index+2]</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>s2[index..<index+2]</div><div class="">compile to</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>let index = 1</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>let index1 = s1.index(s.startIndex, offsetBy: index)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>let index2 = s2.index(s.startIndex, offsetBy: index)</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>s1[index1..<s.index(index1, offsetBy: 2)]</div></div><div class=""><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>s2[index2..<s.index(index2, offsetBy: 2)]</div></div><div class=""><br class=""></div><div class="">I really want the team to consider providing the offset index system as an assistant to the collection. It is the very necessary basic concept of Collection.</div><div class=""><br class=""></div><div class="">Thanks!</div><div class="">Jiannan</div><div class=""><div class=""><br class=""><blockquote type="cite" class=""><div class="">在 2017年12月15日,上午2:13,Jordan Rose <<a href="mailto:jordan_rose@apple.com" class="">jordan_rose@apple.com</a>> 写道:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html; charset=us-ascii" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div class="">We really don't want to make subscripting a non-O(1) operation. That just provides false convenience and encourages people to do the wrong thing with Strings anyway.</div><div class=""><br class=""></div><div class="">I'm always interested in why people want this kind of ability. Yes, it's nice for teaching programming to be able to split strings on character boundaries indexed by integers, but where does it come up in real life? The most common cases I see are trying to strip off the first or last character, or a known prefix or suffix, and I feel like we should have better answers for those than "use integer indexes" anyway.</div><div class=""><br class=""></div><div class="">Jordan</div><br class=""><div class=""><br class=""><blockquote type="cite" class=""><div class="">On Dec 13, 2017, at 22:30, Cao, Jiannan via swift-dev <<a href="mailto:swift-dev@swift.org" class="">swift-dev@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html; charset=us-ascii" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Hi,<div class=""><br class=""></div><div class="">I would like to discuss the String.Index problem within Swift. I know the current situation of String.Index is based on the nature of the underlaying data structure of the string.</div><div class=""><br class=""></div><div class="">But could we just make String.Index contain offset information? Or make offset index subscript available for accessing character in String?</div><div class=""><br class=""></div><div class="">for example:</div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(186, 45, 162);" class="">let</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class=""> a = </span><span style="color: rgb(209, 47, 27); font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">"01234"</span><br class=""><span style="color: rgb(62, 30, 129); font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">print</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">(</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(79, 129, 135);" class="">a</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">[</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(39, 42, 216);" class="">0</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">]) </span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(0, 132, 0);" class="">// 0<br class=""></span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(62, 30, 129);" class="">print</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">(</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(79, 129, 135);" class="">a</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">[</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(39, 42, 216);" class="">0</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">...</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(39, 42, 216);" class="">4</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">]) </span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(0, 132, 0);" class="">// 01234<br class=""></span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(62, 30, 129);" class="">print</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">(</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(79, 129, 135);" class="">a</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">[...]) </span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(0, 132, 0);" class="">// 01234</span><br class=""><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(62, 30, 129);" class="">print</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">(</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(79, 129, 135);" class="">a</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">[..<</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(39, 42, 216);" class="">2</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">]) </span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(0, 132, 0);" class="">// 01<br class=""></span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(62, 30, 129);" class="">print</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">(</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(79, 129, 135);" class="">a</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">[...</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(39, 42, 216);" class="">2</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">]) </span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(0, 132, 0);" class="">// 012<br class=""></span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(62, 30, 129);" class="">print</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">(</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(79, 129, 135);" class="">a</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">[</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(39, 42, 216);" class="">2</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">...]) </span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(0, 132, 0);" class="">// 234<br class=""></span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(62, 30, 129);" class="">print</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">(</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(79, 129, 135);" class="">a</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">[</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(39, 42, 216);" class="">2</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">...</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(39, 42, 216);" class="">3</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">]) </span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(0, 132, 0);" class="">// 23<br class=""></span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(62, 30, 129);" class="">print</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">(</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(79, 129, 135);" class="">a</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">[</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(39, 42, 216);" class="">2</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">...</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(39, 42, 216);" class="">2</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">]) </span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(0, 132, 0);" class="">// 2</span><br class=""><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(186, 45, 162);" class="">if</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class=""> </span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(186, 45, 162);" class="">let</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class=""> number = </span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(79, 129, 135);" class="">a</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">.</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(49, 89, 93);" class="">index</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">(of: </span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(209, 47, 27);" class="">"1"</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">) {<br class=""></span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class=""> </span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(62, 30, 129);" class="">print</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">(number) </span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(0, 132, 0);" class="">// 1<br class=""></span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class=""> </span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(62, 30, 129);" class="">print</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">(</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(79, 129, 135);" class="">a</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">[number...]) </span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(0, 132, 0);" class="">// 1234<br class=""></span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">}</span></blockquote><div class=""><span style="background-color: rgb(255, 255, 255);" class=""><br class=""></span></div><div class=""><br class=""></div><div class=""><span style="background-color: rgb(255, 255, 255);" class="">0 equals to Collection.Index of collection.index(startIndex, offsetBy: 0)</span></div><div class=""><span style="background-color: rgb(255, 255, 255);" class="">1 equals to</span><span style="background-color: rgb(255, 255, 255);" class=""> Collection.Index of collection.index(startIndex, offsetBy: 1)</span></div><div class=""><span style="background-color: rgb(255, 255, 255);" class="">...</span></div><div class=""><span style="background-color: rgb(255, 255, 255);" class="">we keep the String.Index, but allow another kind of index, which is called "offsetIndex" to access the String.Index and the character in the string.</span></div><div class=""><span style="background-color: rgb(255, 255, 255);" class="">Any Collection could use the offset index to access their element, regarding the real index of it.</span></div><div class=""><span style="background-color: rgb(255, 255, 255);" class=""><br class=""></span></div><div class=""><span style="background-color: rgb(255, 255, 255);" class="">I have make the Collection OffsetIndexable protocol available here, and make it more accessible for StringProtocol considering all API related to the index.</span></div><div class=""><span style="background-color: rgb(255, 255, 255);" class=""><br class=""></span></div><div class=""><div class=""><span style="background-color: rgb(255, 255, 255);" class=""><a href="https://github.com/frogcjn/OffsetIndexableCollection-String-Int-Indexable-" class="">https://github.com/frogcjn/OffsetIndexableCollection-String-Int-Indexable-</a></span></div></div><div class=""><span style="background-color: rgb(255, 255, 255);" class=""><br class=""></span></div><div class=""><span style="background-color: rgb(255, 255, 255);" class="">If someone want to make the offset index/range available for any collection, you just need to extend the collection:</span></div><div class=""><pre style="box-sizing: border-box; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.600000381469727px; margin-top: 0px; margin-bottom: 0px; word-wrap: normal; padding: 16px; overflow: auto; line-height: 1.45; background-color: rgb(246, 248, 250); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: normal; color: rgb(36, 41, 46);" class=""><span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">extension</span> <span class="pl-en" style="box-sizing: border-box; color: rgb(111, 66, 193);"><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">String</span></span> : <span class="pl-e" style="box-sizing: border-box; color: rgb(111, 66, 193);">OffsetIndexableCollection </span>{
}
<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">extension</span> <span class="pl-en" style="box-sizing: border-box; color: rgb(111, 66, 193);">Substring</span> : <span class="pl-e" style="box-sizing: border-box; color: rgb(111, 66, 193);">OffsetIndexableCollection </span>{
}</pre><div class=""><br class=""></div></div><div class=""><span style="background-color: rgb(255, 255, 255);" class=""><br class=""></span></div><div class=""><span style="background-color: rgb(255, 255, 255);" class="">I hope the Swift core team could consider bring the offset index to string, or make it available to other collection, thus let developer to decide whether their collection could use offset indices as an assistant for the real index of the collection.</span></div><div class=""><span style="background-color: rgb(255, 255, 255);" class=""><br class=""></span></div><div class=""><br class=""></div><div class=""><span style="background-color: rgb(255, 255, 255);" class="">Thanks!</span></div><div class=""><span style="background-color: rgb(255, 255, 255);" class="">Jiannan</span></div><div class=""><span style="background-color: rgb(255, 255, 255);" class=""><br class=""></span></div><div class=""><span style="background-color: rgb(255, 255, 255);" class=""><br class=""></span></div><div class=""><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="color: rgb(186, 45, 162);" class=""></span></div></blockquote></div></div>_______________________________________________<br class="">swift-dev mailing list<br class=""><a href="mailto:swift-dev@swift.org" class="">swift-dev@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-dev" class="">https://lists.swift.org/mailman/listinfo/swift-dev</a><br class=""></div></blockquote></div><br class=""></div></div></blockquote></div><br class=""></div></div></div>_______________________________________________<br class="">swift-dev mailing list<br class=""><a href="mailto:swift-dev@swift.org" class="">swift-dev@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-dev" class="">https://lists.swift.org/mailman/listinfo/swift-dev</a><br class=""></div></blockquote></div><br class=""></div></div></blockquote></div><br class=""></div></div></div></div></blockquote></div><br class=""></div></div></div></blockquote></div><br class=""></div></div></div></div></div></div></blockquote></div><br class=""></div></div></div>_______________________________________________<br class="">swift-dev mailing list<br class=""><a href="mailto:swift-dev@swift.org" class="">swift-dev@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-dev<br class=""></div></blockquote></div><br class=""></div></body></html>