Сортировка списка Scala, эквивалентного C#, без изменения порядка C#
Я пытаюсь отсортировать список с коллекцией строк в Scala, чей результат должен быть идентичен результату списка C#. Но для следующих данных C# возвращает результат в другом порядке и scala возвращает результат в другом порядке. Может ли кто-нибудь сказать мне, кто должен сделать результат для обоих языков одинаковыми для любого типа строки?
Код C#:
List<String> list = new List<String>();
list.Add("bmw_sip");
list.Add("bmw_mnt");
list.Add("bmw1");
list.Add("bmw");
list.Sort();
foreach (String data in list)
{
Console.Write(data+" ");
}
Выход:
bmw bmw_mnt bmw_sip bmw1
Скала код:
var list = List("bmw_sip", "bmw_mnt", "bmw1", "bmw")
list.sorted
Выход:
List[String] = List(bmw, bmw1, bmw_mnt, bmw_sip)
2 ответа
Реализация Scala sorted
на List[String]
в конечном итоге использует compareTo
метод определяется java.lang.String
, который выполняет лексикографическое сравнение (как подробно объяснено в документе).
Значения Юникода '1'
а также '_'
49 и 95 соответственно на самом деле:
"_" compareTo "1"
// Int = 46
С другой стороны, Sort()
в C# использует Comparer<String>.Default
который выполняет сравнение с учетом локали. Вы можете достичь того же результата в Scala, используя Collator
:
val ord = Ordering.comparatorToOrdering(java.text.Collator.getInstance)
List("bmw_sip", "bmw_mnt", "bmw1", "bmw").sorted(ord)
// List[String] = List(bmw, bmw_mnt, bmw_sip, bmw1)
и просто относиться к предыдущему примеру
ord.compare("_", "1")
// Int = -1
Обратите внимание, что этот способ сортировки зависит от текущей локали (как это было в оригинальном коде C#)
Просто для полноты, если вы вместо этого хотите выполнить лексикографическое сравнение в C#, вы должны использовать StringComparer.Ordinal
:
list.Sort(StringComparer.Ordinal);
Вы можете использовать метод list.Sort() для этого. Метод Sort () вызывает компаратор по умолчанию, если вы хотите изменить способ сортировки, обратитесь к http://msdn.microsoft.com/en-us/library/234b841s(v=vs.110).aspx