<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">The&nbsp;enumerateSubstrings method of (NS)String has a .byComposedCharacterSequences option which causes Emoji sequences like "๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ" to be treated as a single unit:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp; &nbsp;&nbsp;</span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">func</span><span style="font-variant-ligatures: no-common-ligatures" class=""> f(</span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">_</span><span style="font-variant-ligatures: no-common-ligatures" class=""> s: </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">String</span><span style="font-variant-ligatures: no-common-ligatures" class="">) -&gt; [</span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">String</span><span style="font-variant-ligatures: no-common-ligatures" class="">] {</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">var</span><span style="font-variant-ligatures: no-common-ligatures" class=""> a: [</span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">String</span><span style="font-variant-ligatures: no-common-ligatures" class="">] = []</span></div><div style="margin: 0px; line-height: normal; color: rgb(112, 61, 170);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">&nbsp; &nbsp; &nbsp; &nbsp; s.</span><span style="font-variant-ligatures: no-common-ligatures; color: #3e1e81" class="">enumerateSubstrings</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">(in: s.</span><span style="font-variant-ligatures: no-common-ligatures" class="">startIndex</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">..&lt;s.</span><span style="font-variant-ligatures: no-common-ligatures" class="">endIndex</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">, options: .</span><span style="font-variant-ligatures: no-common-ligatures" class="">byComposedCharacterSequences</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">) {</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (c, </span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">_</span><span style="font-variant-ligatures: no-common-ligatures" class="">, </span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">_</span><span style="font-variant-ligatures: no-common-ligatures" class="">, </span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">_</span><span style="font-variant-ligatures: no-common-ligatures" class="">) </span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">in</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">if</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">let</span><span style="font-variant-ligatures: no-common-ligatures" class=""> c = c { a.</span><span style="font-variant-ligatures: no-common-ligatures; color: #3e1e81" class="">append</span><span style="font-variant-ligatures: no-common-ligatures" class="">(c) }</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp; &nbsp; &nbsp; &nbsp; }</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">return</span><span style="font-variant-ligatures: no-common-ligatures" class=""> a</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp; &nbsp; }</span></div><div style="margin: 0px; line-height: normal; min-height: 13px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""></span><br class=""></div><div style="margin: 0px; line-height: normal; font-family: 'Apple Color Emoji'; color: rgb(0, 132, 0);" class=""><span style="line-height: normal; font-family: Menlo; font-variant-ligatures: no-common-ligatures; color: rgb(0, 0, 0);" class="">&nbsp; &nbsp; </span><span style="line-height: normal; font-family: Menlo; font-variant-ligatures: no-common-ligatures; color: rgb(62, 30, 129);" class="">print</span><span style="line-height: normal; font-family: Menlo; font-variant-ligatures: no-common-ligatures; color: rgb(0, 0, 0);" class="">(</span><span style="line-height: normal; font-family: Menlo; font-variant-ligatures: no-common-ligatures; color: rgb(49, 89, 93);" class="">f</span><span style="line-height: normal; font-family: Menlo; font-variant-ligatures: no-common-ligatures; color: rgb(0, 0, 0);" class="">(</span><span style="line-height: normal; font-family: Menlo; font-variant-ligatures: no-common-ligatures; color: rgb(209, 47, 27);" class="">"</span><span style="font-variant-ligatures: no-common-ligatures; color: #d12f1b" class="">๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ๐Ÿ‘ท๐Ÿพโ€โ™€๏ธ</span><span style="line-height: normal; font-family: Menlo; font-variant-ligatures: no-common-ligatures; color: rgb(209, 47, 27);" class="">"</span><span style="line-height: normal; font-family: Menlo; font-variant-ligatures: no-common-ligatures; color: rgb(0, 0, 0);" class="">)) </span><span style="line-height: normal; font-family: Menlo; font-variant-ligatures: no-common-ligatures;" class="">// ["</span><span style="font-variant-ligatures: no-common-ligatures" class="">๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ</span><span style="line-height: normal; font-family: Menlo; font-variant-ligatures: no-common-ligatures;" class="">", "</span><span style="font-variant-ligatures: no-common-ligatures" class="">๐Ÿ‘ท๐Ÿพโ€โ™€๏ธ</span><span style="line-height: normal; font-family: Menlo; font-variant-ligatures: no-common-ligatures;" class="">"]</span></div><div class=""><span style="line-height: normal; font-family: Menlo; font-variant-ligatures: no-common-ligatures;" class=""><br class=""></span></div></div></div><div class=""><span style="line-height: normal; font-family: Menlo; font-variant-ligatures: no-common-ligatures;" class=""><br class=""></span></div><div class="">As I understand it from&nbsp;<a href="https://oleb.net/blog/2016/12/emoji-4-0/" class="">https://oleb.net/blog/2016/12/emoji-4-0/</a>, Emoji sequences are considered as a single grapheme cluster in Unicode 9, which means that you can simply do something like</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">&nbsp; &nbsp; Array</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">(</span><span style="font-variant-ligatures: no-common-ligatures" class="">"</span><span style="line-height: normal; font-family: 'Apple Color Emoji'; font-variant-ligatures: no-common-ligatures;" class="">๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ๐Ÿ‘ท๐Ÿพโ€โ™€๏ธ</span><span style="font-variant-ligatures: no-common-ligatures" class="">"</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">.</span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">characters</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">)</span></div></div><div class=""><br class=""></div><div class="">once Unicode 9 is adopted in Swift.</div><div class=""><br class=""></div><div class="">Regards, Martin</div><div class=""><br class=""></div><div class=""><br class=""></div><div><blockquote type="cite" class=""><div class="">On 12. May 2017, at 10:43, Jens Persson via swift-users &lt;<a href="mailto:swift-users@swift.org" class="">swift-users@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><div class="">I want a function f such that:</div><div class=""><br class=""></div><div class="">f("abc") == ["a", "b", "c"]</div><div class=""><br class=""></div><div class="">f("cafรฉ") == ["c", "a", "f", "รฉ"]</div><div class=""><br class=""></div><div class="">f("๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ๐Ÿ‘ท๐Ÿพโ€โ™€๏ธ") == ["๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ", "๐Ÿ‘ท๐Ÿพโ€โ™€๏ธ"]</div><div class=""><br class=""></div><div class="">I'm not sure if the last example renders correctly by mail for everyone but the input String contains these _two_ "natural/visual characters":</div><div class="">(1) A family emoji</div><div class="">(2) a construction worker (woman, with skin tone modifier) emoji.</div><div class="">and the result is an Array of two strings (one for each emoji).</div><div class=""><br class=""></div><div class="">The first two examples are easy, the third example is the tricky one.</div><div class=""><br class=""></div><div class=""><div class="">Is there a (practical) way to do this (in Swift 3)?</div></div><div class=""><br class=""></div><div class="">/Jens</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">PS</div><div class=""><br class=""></div><div class="">It's OK if the function has to depend on eg a graphics context etc.</div><div class="">(I tried writing a function so that it extracts the glyphs, using NSTextStorage, NSLayoutManager and the AppleColorEmoji font, but it says that "๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ๐Ÿ‘ท๐Ÿพโ€โ™€๏ธ" contains 18(!) glyphs, whereas eg "cafรฉ" contains 4 as expected.)</div><div class=""><br class=""></div><div class=""><div class="">If the emojis of the third example doesn't look like they should in this mail, here is another way to write the exact same example using only simple text:</div><div class=""><br class=""></div><div class="">let inputOfThirdExample = "\u{1F468}\u{200D}\u{1F469}\u{200D}\u{1F467}\u{200D}\u{1F466}\u{1F477}\u{1F3FE}\u{200D}\u{2640}\u{FE0F}"<br class=""></div><div class=""><br class=""></div><div class="">let result = f(inputOfThirdExample)</div><div class=""><div class=""><br class=""></div><div class="">let expectedResult = ["\u{1F468}\u{200D}\u{1F469}\u{200D}\u{1F467}\u{200D}\u{1F466}", "\u{1F477}\u{1F3FE}\u{200D}\u{2640}\u{FE0F}"]</div><div class=""><br class=""></div><div class="">print(result.elementsEqual(result)) // Should print true<br class=""></div></div></div><div class=""><br class=""></div><div class=""><br class=""></div></div>
_______________________________________________<br class="">swift-users mailing list<br class=""><a href="mailto:swift-users@swift.org" class="">swift-users@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-users<br class=""></div></blockquote></div><br class=""></body></html>