stringflutterunicodedartsurrogate-pairs

How to reverse strings that contain surrogate pairs in Dart?


I was playing with algorithms using Dart and as I actually followed TDD, I realized that my code has some limitations.

I was trying to reverse strings as part of an interview problem, but I couldn't get the surrogate pairs correctly reversed.

const simple = 'abc';
const emoji = '๐ŸŽ๐Ÿ๐Ÿ›';
const surrogate = '๐Ÿ‘ฎ๐Ÿฝโ€โ™‚๏ธ๐Ÿ‘ฉ๐Ÿฟโ€๐Ÿ’ป';

String rev(String s) {
    return String.fromCharCodes(s.runes.toList().reversed);
}

void main() {
    print(simple);
    print(rev(simple));
    print(emoji);
    print(rev(emoji));
    print(surrogate);
    print(rev(surrogate));
}

The output:

abc
cba
๐ŸŽ๐Ÿ๐Ÿ›
๐Ÿ›๐Ÿ๐ŸŽ
๐Ÿ‘ฎ๐Ÿฝโ€โ™‚๏ธ๐Ÿ‘ฉ๐Ÿฟโ€๐Ÿ’ป
๐Ÿ’ปโ€๐Ÿฟ๐Ÿ‘ฉ๏ธโ™‚โ€๐Ÿฝ๐Ÿ‘ฎ

You can see that the simple emojis are correctly reversed as I'm using the runes instead of just simply executing s.split('').toList().reversed.join(''); but the surrogate pairs are reversed incorrectly.

How can I reverse a string that might contain surrogate pairs using the Dart programming language?


Solution

  • When reversing strings, you must operate on graphemes, not characters nor code units. Use grapheme_splitter.