Сравнение, сортируя и ища строковые объекты
Базовые строковые объекты Основы включают много функций для поиска содержания строк и для сравнения двух строк. Поскольку эти операции семантически связаны, не удивительно что основные функции для каждой работы —CFStringFindWithOptions
и CFStringCompareWithOptions
— имейте некоторые общие черты. Их первые четыре параметра почти идентичны: две ссылки на объекты CFString (строки, которые будут сравнены или подстрока для нахождения в основной строке), диапазон символов для включения в работу и битовую маску для указания опций. При сортировке строк для представления пользователю, необходимо выполнить локализованное сравнение с локальным использованием пользователя CFStringCompareWithOptionsAndLocale
.
Сравнение и поиск строк
Несмотря на то, что CFStringFindWithOptions
и CFStringCompareWithOptions
имейте функции вместе, у них есть важные различия также. CFStringCompareWithOptions
функционируйте возвращает результат типа Comparison Results
; это enum
постоянный указывает, сочло ли сравнение строки равными или была ли первая указанная строка больше, чем или меньше, чем вторая строка. CFStringFindWithOptions
функция, с другой стороны, возвращает a Boolean
результат, указывающий успех работы. Более полезным результатом, возвращенным косвенно этой функцией, является диапазон (структура типа CFRange
) указанный его заключительным параметром; этот диапазон содержит расположение найденной строки в основной строке.
Перечисление 1 иллюстрирует использование обоих CFStringCompareWithOptions
и CFStringFindWithOptions
(это также использует show
функция, данная в Перечислении 2 Создания и Копирования Строк).
В этом примере оба выдерживает сравнение находка и, функции указывают kCFCompareCaseInsensitive
отметьте как опция для работы, заставив его проигнорировать различия в случае, если. Другие флаги опции доступны, включая kCFCompareBackwards
(запустите работу с конца строки), kCFCompareNumerically
(сравните подобные строки, содержащие числовые подстроки численно), и kCFCompareLocalized
(используйте локаль пользователя по умолчанию для работы).
Перечисление 1 , Выдерживающее сравнение и ищущее содержание CFString
void compareAndSearchStringsExample() { |
CFStringRef str1 = CFSTR("ABCDEFG"); |
CFStringRef str2 = CFSTR("abcdefg"); |
CFStringRef str3 = CFSTR("Kindergarten is the time to start teaching the ABCDEFG's"); |
CFRange foundRange; |
CFComparisonResult result; |
result = CFStringCompareWithOptions(str1, str2, CFRangeMake(0,CFStringGetLength(str1)), kCFCompareCaseInsensitive); |
if (result == kCFCompareEqualTo) { |
show(CFSTR("%@ is the same as %@"), str1, str2); |
} else { |
show(CFSTR("%@ is not the same as %@"), str1, str2); |
} |
if ( CFStringFindWithOptions(str3, str1, CFRangeMake(0,CFStringGetLength(str3)), kCFCompareCaseInsensitive, &foundRange) == true ) { |
show(CFSTR("The string \"%@\" was found at index %d in string \"%@\"."), str1, foundRange.location, str3); |
} else { |
show(CFSTR("The string \"%@\" was not found in string \"%@\"."), str1, str3); |
} |
} |
Этот код генерирует следующий вывод:
ABCDEFG is the same as abcdefg |
The string "ABCDEFG" was found at index 47 in string "Kindergarten is the time to start teaching the ABCDEFG's". |
По умолчанию основанием для сравнения объектов CFString является познаковое литеральное сравнение. При некоторых обстоятельствах это может не дать, Вы заканчиваетесь, Вы ожидаете, так как некоторые символы могут быть представлены несколькими различными способами (например, «Ф» может быть представлен как два отличных символа («o» и «умляут») или отдельным символом («o-умляут»). Если Вы хотите позволить свободную эквивалентность, используйте поиск или сравните функцию с kCFCompareNonliteral
отметьте как опция. Обратите внимание на то, что при указании нелитерального сравнения длина диапазона, возвращенного из функции находки, не могла бы совпасть с длиной строки поиска.
В дополнение к основному сравнивают и находят функции, строковые объекты обеспечивают некоторые функции удобства. CFStringFind
и CFStringCompare
подобны «основным» функциям, описанным выше, но они не требуют спецификации диапазона (вся строка принята). Обратите внимание на то, что можно использовать CFStringCompare
в другом месте в Базовой Основе, когда указатель функции, соответствующий CFComparatorFunction
тип требуется.
Другой поиск и функции сравнения строковых объектов CFStringHasPrefix
, CFStringHasSuffix
, и CFStringCreateArrayWithFindResults
. Когда Вы ожидаете многократные хиты с поисковой работой, последняя из этих функций полезна; это возвращает массив CFRange
структуры, каждая из которых указывает расположение соответствующей подстроки в основной строке.
Сортировка строк
Если Вы сортируете строки и представляете результаты пользователю, необходимо удостовериться, что Вы выполняете локализованное сравнение с помощью локали пользователя. Можно также хотеть расположить строки, поскольку они появились бы в Средстве поиска — например, эти строки {«Представляют в виде строки 12», «Строка 1», «представляют в виде строки 22», «представляют в виде строки 02»}, должна быть сортирована, поскольку {«Представляют в виде строки 1», «представляют в виде строки 02», «Представляют в виде строки 12», «представляют в виде строки 22»}.
Для достижения этого можно использовать CFStringCompareWithOptionsAndLocale
с опциями kCFCompareCaseInsensitive
, kCFCompareNonliteral
, kCFCompareLocalized
, kCFCompareNumerically
, kCFCompareWidthInsensitive
, и kCFCompareForcedOrdering
. Во-первых, реализуйте функцию для выполнения надлежащего сравнения:
CFComparisonResult CompareStringsLikeFinderWithLocale ( |
const void *string1, const void *string2, void *locale) |
{ |
static CFOptionFlags compareOptions = kCFCompareCaseInsensitive | |
kCFCompareNonliteral | |
kCFCompareLocalized | |
kCFCompareNumerically | |
kCFCompareWidthInsensitive | |
kCFCompareForcedOrdering; |
CFRange string1Range = CFRangeMake(0, CFStringGetLength(string1)); |
return CFStringCompareWithOptionsAndLocale |
(string1, string2, string1Range, compareOptions, (CFLocaleRef)locale); |
} |
Тогда выполните сравнение с помощью той функции:
// ignore memory management for the sake of clarity and brevity |
CFMutableArrayRef theArray = CFArrayCreateMutable(kCFAllocatorDefault, 4, NULL); |
CFArrayAppendValue(theArray, CFSTR("String 12")); |
CFArrayAppendValue(theArray, CFSTR("String 1")); |
CFArrayAppendValue(theArray, CFSTR("string 22")); |
CFArrayAppendValue(theArray, CFSTR("string 02")); |
CFRange arrayRange = CFRangeMake(0, CFArrayGetCount(theArray)); |
CFLocaleRef locale = CFLocaleCopyCurrent(); |
CFArraySortValues (theArray, arrayRange, |
CompareStringsLikeFinderWithLocale, (void *)locale); |
// theArray now contains { "String 1", "string 02", "String 12", "string 22" } |