Сравнение, сортируя и ища строковые объекты

Базовые строковые объекты Основы включают много функций для поиска содержания строк и для сравнения двух строк. Поскольку эти операции семантически связаны, не удивительно что основные функции для каждой работы —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" }