<html><head><meta http-equiv="Content-Type" content="text/html; charset=gb2312"></head><body 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="">OK, but how do you use IndexingIterator to get element and not change itself?</div><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><br class=""></div><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">In C++, the iterator is more like index. because it could be used to get the element, and not change itself, and it can be offset back and forth not only by one.</div><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>*it</div><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>*(it+5)</div><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>*(it-5)</div><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">but in Swift,</div><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">you can only using next() to get the element and change the iterator to point to the next item:</div><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>it.next()</div><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>it.next()</div><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>it.next()</div><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>it.next()</div><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>it.next()</div><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">and you could not go to previous item.</div><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><br class=""></div><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><br class=""></div><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">The iterator in Swift could not be used as index.<br class=""><div class=""><div class=""><br class=""></div><div class=""><div class=""><blockquote type="cite" class=""><div class="">在 2017年12月19日,上午3:00,Michael Ilseman &lt;<a href="mailto:milseman@apple.com" class="">milseman@apple.com</a>&gt; 写道:</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="">An index that keeps a reference to the collection is an iterator, e.g. the IndexingIterator[1], which String already provides.<br class=""><div class=""><br class=""></div><div class="">[1]&nbsp;<a href="https://developer.apple.com/documentation/swift/indexingiterator" class="">https://developer.apple.com/documentation/swift/indexingiterator</a></div><div class=""><br class=""></div><div class=""><br class=""><blockquote type="cite" class=""><div class="">On Dec 18, 2017, at 12:53 AM, Cao, Jiannan &lt;<a href="mailto:frogcjn@163.com" class="">frogcjn@163.com</a>&gt; 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=""><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,&nbsp;since it keeps a reference to the&nbsp;collection&nbsp;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: &quot;Fira Code&quot;;" class=""> </span><span style="color: #ba2da2" class="">struct</span><span style="font-stretch: normal; line-height: normal; font-family: &quot;Fira Code&quot;;" class=""> MyIndex&lt;T: </span>Collection<span style="font-stretch: normal; line-height: normal; font-family: &quot;Fira Code&quot;;" class="">&gt; : </span>Comparable<span style="font-stretch: normal; line-height: normal; font-family: &quot;Fira Code&quot;;" class=""> </span><span style="color: #ba2da2" class="">where</span><span style="font-stretch: normal; line-height: normal; font-family: &quot;Fira Code&quot;;" class=""> </span>T<span style="font-stretch: normal; line-height: normal; font-family: &quot;Fira Code&quot;;" class="">.</span>Index<span style="font-stretch: normal; line-height: normal; font-family: &quot;Fira Code&quot;;" class=""> == </span>MyIndex<span style="font-stretch: normal; line-height: normal; font-family: &quot;Fira Code&quot;;" class=""> {</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: &quot;Fira Code&quot;;" class="">&nbsp; &nbsp; <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: &quot;Fira Code&quot;;" 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: &quot;Fira Code&quot;;" class="">&nbsp; &nbsp; </span><span style="color: #ba2da2" class="">public</span><span style="font-stretch: normal; line-height: normal; font-family: &quot;Fira Code&quot;;" class=""> </span><span style="color: #ba2da2" class="">static</span><span style="font-stretch: normal; line-height: normal; font-family: &quot;Fira Code&quot;;" class=""> </span><span style="color: #ba2da2" class="">func</span><span style="font-stretch: normal; line-height: normal; font-family: &quot;Fira Code&quot;;" class=""> + (lhs: </span><span style="color: #703daa" class="">MyIndex</span><span style="font-stretch: normal; line-height: normal; font-family: &quot;Fira Code&quot;;" class="">, rhs: </span><span style="color: #703daa" class="">T</span><span style="font-stretch: normal; line-height: normal; font-family: &quot;Fira Code&quot;;" class="">.</span><span style="color: #703daa" class="">IndexDistance</span><span style="font-stretch: normal; line-height: normal; font-family: &quot;Fira Code&quot;;" class="">) -&gt; </span><span style="color: #703daa" class="">MyIndex</span><span style="font-stretch: normal; line-height: normal; font-family: &quot;Fira Code&quot;;" class=""> {</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: &quot;Fira Code&quot;;" class="">&nbsp; &nbsp; &nbsp; &nbsp; <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: &quot;Fira Code&quot;;" class="">&nbsp; &nbsp; }</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: &quot;Fira Code&quot;;" 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 &lt;<a href="mailto:milseman@apple.com" class="">milseman@apple.com</a>&gt; 写道:</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 &lt;<a href="mailto:frogcjn@163.com" class="">frogcjn@163.com</a>&gt; 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.&nbsp;<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 &lt;<a href="mailto:milseman@apple.com" class="">milseman@apple.com</a>&gt; 写道:</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 &lt;<a href="mailto:swift-dev@swift.org" class="">swift-dev@swift.org</a>&gt; 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: &quot;SF Mono&quot;, Menlo, monospace, &quot;SF Pro Icons&quot;; 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>&nbsp;<span class="syntax-param-name" style="box-sizing: inherit; color: rgb(64, 64, 64);">offset</span>:&nbsp;<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&nbsp;</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: &quot;SF Mono&quot;, Menlo, monospace, &quot;SF Pro Icons&quot;; letter-spacing: -0.027em; line-height: 1.26667;" class=""><span class="syntax-keyword" style="box-sizing: inherit; color: rgb(170, 13, 145);">var</span>&nbsp;<span class="syntax-identifier" style="box-sizing: inherit;">encodedOffset</span>:&nbsp;<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>&nbsp;{&nbsp;<span class="syntax-keyword" style="box-sizing: inherit; color: rgb(170, 13, 145);">get</span>&nbsp;}</code></pre><div class=""><br class=""></div></div></div><div class=""><br class=""></div><div class="">[1]&nbsp;<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.&nbsp;</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&lt;String.Index&gt; is not as directly as Range&lt;Offset&gt;. Developers need to transfer the Range&lt;String.Index&gt; result of string.range(of:) to Range&lt;OffsetIndex&gt; to know the exact range of the substring. Range&lt;String.Index&gt; has a real meaning to the machine and underlaying data location for the substring, but Range&lt;OffsetIndex&gt; also has a direct location information for human being, and represents<b class=""> the abstract location concept of the collection (This is the most&nbsp;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.&nbsp;Each element of the collection could be located by offset, which is a direct and simple conception to any collection. Right?&nbsp;</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.&nbsp;</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="">&nbsp;</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)&nbsp;</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:&nbsp;<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 =&nbsp;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..&lt;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..&lt;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..&lt;index+2]</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>s2[index..&lt;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 =&nbsp;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..&lt;s.index(index1, offsetBy: 2)]</div></div><div class=""><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>s2[index2..&lt;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 &lt;<a href="mailto:jordan_rose@apple.com" class="">jordan_rose@apple.com</a>&gt; 写道:</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 &lt;<a href="mailto:swift-dev@swift.org" class="">swift-dev@swift.org</a>&gt; 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="">[..&lt;</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="">&nbsp; &nbsp;&nbsp;</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="">&nbsp; &nbsp;&nbsp;</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="">&nbsp;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&nbsp;more&nbsp;accessible&nbsp;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, &quot;Liberation Mono&quot;, 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&nbsp;available to other collection, thus let&nbsp;developer to decide whether&nbsp;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></blockquote></div><br class=""></div></div></div></div></body></html>