<div dir="ltr">I think there’s a middle ground here as the current API is overly complex and general. 95% of the time people are dealing with ASCII strings and don’t care about things like unicode cluster boundaries and whatnot<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Dec 14, 2017 at 12:13 PM, Jordan Rose via swift-dev <span dir="ltr">&lt;<a href="mailto:swift-dev@swift.org" target="_blank">swift-dev@swift.org</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word;line-break:after-white-space"><div>We really don&#39;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><br></div><div>I&#39;m always interested in why people want this kind of ability. Yes, it&#39;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 &quot;use integer indexes&quot; anyway.</div><div><br></div><div>Jordan</div><br><div><br><blockquote type="cite"><div><div class="h5"><div>On Dec 13, 2017, at 22:30, Cao, Jiannan via swift-dev &lt;<a href="mailto:swift-dev@swift.org" target="_blank">swift-dev@swift.org</a>&gt; wrote:</div><br class="m_-5118163137131845892Apple-interchange-newline"></div></div><div><div><div class="h5"><div style="word-wrap:break-word;line-break:after-white-space">Hi,<div><br></div><div>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><br></div><div>But could we just make String.Index contain offset information? Or make offset index subscript available for accessing character in String?</div><div><br></div><div>for example:</div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255);color:rgb(186,45,162)">let</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255)"> a = </span><span style="color:rgb(209,47,27);font-family:Menlo;font-size:11px;background-color:rgb(255,255,255)">&quot;01234&quot;</span><br><span style="color:rgb(62,30,129);font-family:Menlo;font-size:11px;background-color:rgb(255,255,255)">print</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255)">(</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255);color:rgb(79,129,135)">a</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255)">[</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255);color:rgb(39,42,216)">0</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255)">]) </span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255);color:rgb(0,132,0)">// 0<br></span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255);color:rgb(62,30,129)">print</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255)">(</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255);color:rgb(79,129,135)">a</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255)">[</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255);color:rgb(39,42,216)">0</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255)">...</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255);color:rgb(39,42,216)">4</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255)">]) </span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255);color:rgb(0,132,0)">// 01234<br></span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255);color:rgb(62,30,129)">print</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255)">(</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255);color:rgb(79,129,135)">a</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255)">[...]) </span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255);color:rgb(0,132,0)">// 01234</span><br><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255);color:rgb(62,30,129)">print</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255)">(</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255);color:rgb(79,129,135)">a</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255)">[..&lt;</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255);color:rgb(39,42,216)">2</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255)">]) </span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255);color:rgb(0,132,0)">// 01<br></span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255);color:rgb(62,30,129)">print</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255)">(</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255);color:rgb(79,129,135)">a</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255)">[...</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255);color:rgb(39,42,216)">2</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255)">]) </span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255);color:rgb(0,132,0)">// 012<br></span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255);color:rgb(62,30,129)">print</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255)">(</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255);color:rgb(79,129,135)">a</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255)">[</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255);color:rgb(39,42,216)">2</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255)">...]) </span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255);color:rgb(0,132,0)">// 234<br></span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255);color:rgb(62,30,129)">print</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255)">(</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255);color:rgb(79,129,135)">a</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255)">[</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255);color:rgb(39,42,216)">2</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255)">...</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255);color:rgb(39,42,216)">3</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255)">]) </span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255);color:rgb(0,132,0)">// 23<br></span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255);color:rgb(62,30,129)">print</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255)">(</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255);color:rgb(79,129,135)">a</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255)">[</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255);color:rgb(39,42,216)">2</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255)">...</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255);color:rgb(39,42,216)">2</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255)">]) </span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255);color:rgb(0,132,0)">// 2</span><br><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255);color:rgb(186,45,162)">if</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255)"> </span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255);color:rgb(186,45,162)">let</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255)"> number = </span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255);color:rgb(79,129,135)">a</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255)">.</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255);color:rgb(49,89,93)">index</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255)">(of: </span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255);color:rgb(209,47,27)">&quot;1&quot;</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255)">) {<br></span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255)">    </span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255);color:rgb(62,30,129)">print</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255)">(number) </span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255);color:rgb(0,132,0)">// 1<br></span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255)">    </span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255);color:rgb(62,30,129)">print</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255)">(</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255);color:rgb(79,129,135)">a</span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255)">[number...]) </span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255);color:rgb(0,132,0)">// 1234<br></span><span style="font-family:Menlo;font-size:11px;background-color:rgb(255,255,255)">}</span></blockquote><div><span style="background-color:rgb(255,255,255)"><br></span></div><div><br></div><div><span style="background-color:rgb(255,255,255)">0 equals to Collection.Index of collection.index(startIndex, offsetBy: 0)</span></div><div><span style="background-color:rgb(255,255,255)">1 equals to</span><span style="background-color:rgb(255,255,255)"> Collection.Index of collection.index(startIndex, offsetBy: 1)</span></div><div><span style="background-color:rgb(255,255,255)">...</span></div><div><span style="background-color:rgb(255,255,255)">we keep the String.Index, but allow another kind of index, which is called &quot;offsetIndex&quot; to access the String.Index and the character in the string.</span></div><div><span style="background-color:rgb(255,255,255)">Any Collection could use the offset index to access their element, regarding the real index of it.</span></div><div><span style="background-color:rgb(255,255,255)"><br></span></div><div><span style="background-color:rgb(255,255,255)">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><span style="background-color:rgb(255,255,255)"><br></span></div><div><div><span style="background-color:rgb(255,255,255)"><a href="https://github.com/frogcjn/OffsetIndexableCollection-String-Int-Indexable-" target="_blank">https://github.com/frogcjn/<wbr>OffsetIndexableCollection-<wbr>String-Int-Indexable-</a></span></div></div><div><span style="background-color:rgb(255,255,255)"><br></span></div><div><span style="background-color:rgb(255,255,255)">If someone want to make the offset index/range available for any collection, you just need to extend the collection:</span></div><div><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)"><span class="m_-5118163137131845892pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">extension</span> <span class="m_-5118163137131845892pl-en" style="box-sizing:border-box;color:rgb(111,66,193)"><span class="m_-5118163137131845892pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">String</span></span> : <span class="m_-5118163137131845892pl-e" style="box-sizing:border-box;color:rgb(111,66,193)">OffsetIndexableCollection </span>{
}

<span class="m_-5118163137131845892pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">extension</span> <span class="m_-5118163137131845892pl-en" style="box-sizing:border-box;color:rgb(111,66,193)">Substring</span> : <span class="m_-5118163137131845892pl-e" style="box-sizing:border-box;color:rgb(111,66,193)">OffsetIndexableCollection </span>{
}</pre><div><br></div></div><div><span style="background-color:rgb(255,255,255)"><br></span></div><div><span style="background-color:rgb(255,255,255)">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><span style="background-color:rgb(255,255,255)"><br></span></div><div><br></div><div><span style="background-color:rgb(255,255,255)">Thanks!</span></div><div><span style="background-color:rgb(255,255,255)">Jiannan</span></div><div><span style="background-color:rgb(255,255,255)"><br></span></div><div><span style="background-color:rgb(255,255,255)"><br></span></div><div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div style="margin:0px;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;background-color:rgb(255,255,255)"><span style="color:rgb(186,45,162)"></span></div></blockquote></div></div></div></div>______________________________<wbr>_________________<br>swift-dev mailing list<br><a href="mailto:swift-dev@swift.org" target="_blank">swift-dev@swift.org</a><br><a href="https://lists.swift.org/mailman/listinfo/swift-dev" target="_blank">https://lists.swift.org/<wbr>mailman/listinfo/swift-dev</a><br></div></blockquote></div><br></div><br>______________________________<wbr>_________________<br>
swift-dev mailing list<br>
<a href="mailto:swift-dev@swift.org">swift-dev@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-dev" rel="noreferrer" target="_blank">https://lists.swift.org/<wbr>mailman/listinfo/swift-dev</a><br>
<br></blockquote></div><br></div>