In Dart, if I have a list:
final myList = ['b', 'a'];
and I wanted to sort it alphabetically, I would use:
myList.sort(
(String a, String b) => a.compareTo(b),
);
The output of myList
is now:
['a', 'b']
Now, this works on letters that are in the English alphabet.
But if I have a list that's in Hebrew:
final unorderedHebAlphabet = ['א', 'ב'];
I can't sort it as above using with:
unorderedHebAlphabet.sort((String a, String b) =>
a.compareTo(b))
It doesn't sort.
Expected output, instead of:
['א', 'ב']
Should be:
['ב', 'א']
As a reference, the Hebrew alphabet sorted would be in this order:
final sortedHebrewAlphabet = [
'א',
'ב',
'ג',
'ד',
'ה',
'ו',
'ז',
'ח',
'ט',
'י',
'כ',
'ל',
'מ',
'נ',
'ס',
'ע',
'פ',
'צ',
'ק',
'ר',
'ש',
'ת',
];
It does sort (by UTF-16 code units), but it's being shown in an unintuitive way. final unorderedHebAlphabet = ['א', 'ב'];
seems to be parsed RTL, so in the constructed list, element 0 is א
and element 1 is ב
. That's already the desired order, so sorting it does not change it. (Mixing LTR and RTL text is confusing.)
For example:
import 'package:collection/collection.dart';
void main() {
var literal = ['א', 'ב'];
print(literal[0]); // Prints: א
print(literal[1]); // Prints: ב
const alef = 'א';
const bet = 'ב';
const expectedOrder = [alef, bet];
const listEquals = ListEquality<String>();
print(listEquals.equals(literal..sort(), expectedOrder)); // Prints: true
print(listEquals.equals([bet, alef]..sort(), expectedOrder)); // Prints: true
}
You also can observe that the elements are printed in the correct order if you prefix output with the Unicode LTR override (U+202D) to force rendering the text as LTR. Compare:
const ltr = '\u202D';
print('$expectedOrder');
print('$ltr$expectedOrder');
Or you could simply print the elements separately:
expectedOrder.forEach(print);
which prints:
א
ב
I'm not experienced with dealing with RTL text, but I'd probably avoid mixing LTR and RTL text in code and instead express them as hexadecimal Unicode code points to avoid confusion.