CFStringCompare и сортировка без учета регистра
Наша цель - написать сопоставление без учета регистра для базы данных SQLite. Мы сделали это для нескольких платформ, но у iOS, похоже, есть постоянные проблемы, которые (иногда) проявляются в поврежденных индексах БД. После долгих экспериментов мы пришли к выводу, что виновником является функция CFStringCompare(), которая нарушает теоретические правила.
Точность. Согласно теории, функция сравнения должна быть рефлексивной, симметричной и транзитивной.
Мы создали случайные строки и проверили, отвечает ли CFStringCompare() указанным выше свойствам.
Вот пример проблемы: CFStringCompare с флагами NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch привел:
"Я7;1FC9" > "SДA`\"0l"
"SДA`\"0l" > "Я7;1FC9"
Другими словами, A>B в то же время, когда B>A!
Мы протестировали больше комбинаций флагов:
- kCFCompareNonliteral показал аналогичные проблемы
- kCFCompareLocalized оказался худшим вариантом (большинство проблем)
Кто-нибудь знает о безопасном способе проведения сравнения без учета регистра в iOS?
1 ответ
Хорошо, нет ответа, поэтому я постараюсь ответить сам.
Прежде всего, другие люди наблюдали похожие проблемы, например, по этой ссылке. Обратите внимание, что мы также наблюдали много проблем с немецким ß. Я выбрал другой пример случайно.
Этого должно быть достаточно, чтобы сказать, что CFStringCompare имеет ошибочную реализацию и не может использоваться для сортировки.
С другой стороны, есть библиотека ICU, и они заявляют о полном соответствии с UCA (например, здесь), который в свою очередь должен подчиняться всем теоретическим правилам.
Таким образом, мой ответ будет: CFStringCompare глючит, используйте ICU.
(Я надеялся на другой ответ из-за огромного размера библиотеки ICU)