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)

Другие вопросы по тегам