2015-05-08 3 views
0

Я пытаюсь понять, сравнивая NSString рутину. Пожалуйста, обратите внимание на следующий код:Сравнение одного NSString больше или меньше другого NSString

// String 

    NSString *str1 = @"This is a string A"; 

    NSString *str2 = @"This is a string B"; 

    NSString *res; 

    NSComparisonResult compareResult; 

compareResult = [str1 compare:str2]; 

    if (compareResult == NSOrderedAscending) 
     NSLog(@"str1 < str2"); 

    if (compareResult == NSOrderedSame) 
     NSLog(@"str1 == str2"); 
    else // must be NSOrderedDescending 
     NSLog(@"str1 > str2"); 

Мой первый вопрос в том, как мы можем определить, является NSString больше или меньше, чем другой? Это не число, так как именно мы его определяем?

NSString состоит из символов Unichar, размер которых составляет 16 бит. Может быть, компилятор определяет фактический размер каждой строки и сравнивает ее?

Мой второй вопрос: enter image description here

Все условия выполнены. Как это могло случиться? Строки разные, и мы получили все 3 возможных результата: str1 больше str2, меньше str2 и равно.

+1

Сравнение строк выполняет лексическое упорядочение на основе каждого символа. В упрощенных выражениях он в основном выполняет буквенное сравнение. «B» больше, чем «A», например, так как B появляется после A. Теперь расширьте это, чтобы покрыть каждый символ Юникода. – rmaddy

+1

Обратите внимание, что результаты сравнения в порядке, не более или менее. – zaph

+0

Прочитайте тонкую спецификацию. (Но вышеприведенный код не мог произвести вышеупомянутый вывод консоли.) –

ответ

2

Обратите внимание, что результаты сравнения в порядке, не больше или меньше. Не приравнивайте заказ к более или менее.

Заказ по соглашению основан на алфавитном порядке.

Хотя длина является характеристикой строки, она немного сложнее, чем с юникодом, поскольку для одного символа может потребоваться больше одной кодовой точки юникода.

Также NSString не является строкой unichars, но кажется (фактическая реализация непрозрачной) последовательностью или кодовыми точками UTF-16.

Код:

if (compareResult == NSOrderedAscending) 
    NSLog(@"str1 < str2"); 

if (compareResult == NSOrderedSame) 
    NSLog(@"str1 == str2"); 
else // must be NSOrderedDescending 
    NSLog(@"str1 > str2"); 

несовершенна, она должна быть (обратите внимание на else if):

if (compareResult == NSOrderedAscending) 
    NSLog(@"str1 preceeds str2"); 
else if (compareResult == NSOrderedSame) 
    NSLog(@"str1 is the same as str2"); 
else // must be NSOrderedDescending 
    NSLog(@"str1 follows str2"); 

В результате на выходе:

str1 предшествует str2

+0

если я правильно понял, если (compareResult == NSOrderedSame) NSLog (@ "str1 == str2"); else // должен быть NSOrderedDescending NSLog (@ "str1> str2"); вторая строка печатает NSLog для условия, когда str1 предшествует str2? –

+0

В вопросительном коде ths второй оператор 'if' всегда будет выполняться и всегда регистрирует значение. Этого вы не хотите, вы хотите, чтобы второй оператор 'if' выполнялся, если первый оператор' if' неверен. – zaph

+0

Я провел некоторое тестирование с кодом, когда я изменяю str1 на @ "a" и str2 на @ "b" i получил результат str1 предшествует str2. Когда я сделал str1 = @ "b" и str2 = @ "a" (значения подкачки), я получил тот же результат. Это выглядит странно и запутанно, почему это происходит? –

2

В какао compare: возвращает один из трех кодов:

enum { 
    NSOrderedAscending = -1, 
    NSOrderedSame, 
    NSOrderedDescending 
}; 
typedef NSInteger NSComparisonResult; 

Как вы видите, он не использует больше или меньше, но по убыванию, по возрастанию и то же.

для сортировки цифр соответствует <,>, ==, но в строках он соответствует по алфавиту.


При сравнении строк знать о compare: -alernatives

  • - caseInsensitiveCompare: @ "ABC" и @ "ABC" считаются же
  • - localizedCompare:, как сравнить, но знает, как обращаться с языком конкретных алфавитов
  • - localizedCaseInsensitiveCompare: Объединение 2 предыдущих
  • ...
+0

спасибо, ясный ответ. –

+0

Вы действительно хотите заказать строку по длине? – vikingosegundo

+0

Мне просто интересно, как мы можем сравнить две строки. Потому что они на самом деле просто кусок байтов, и мне интересно, как Xcode делает сравнение. –

3

это очень сложный вопрос, и некоторые детали описаны здесь:

http://unicode.org/reports/tr10/

один пример:
STRING_1 состоит из ('B', диэрезисом, 'а')
STRING_2 состоит из ('B', 'A')
('A' является 'а' с диэрезисом (две точки))
оба оказываемые '' bÃ
обе строки содержат 2 глифы
string_1 содержит 3 пунктов кода
string_2 содержит 2 очка кода
в UTF-16 (родная кодировка NSString) string_1 имеет длину 6 байт, а string_2 имеет длину 4 байта. NSString -длина из них 3 и 2.

это означает, что вы не должны думать, что две строки отличаются только потому, что они имеют разные length;)

обе строки равны в соответствии с правилами сравнения NSString.

[STRING_1 сравнения: STRING_2] вернет NSOrderedSame
[String_1 IsEqual: STRING_2] вернет YES

... то есть без учета регистра-сравнить, а затем есть локализация-известно-сравнить ...

+0

спасибо, ответ велик, но неужели вы так добры, чтобы представить пример с помощью других строк? Мне жаль, но я не понимаю, почему они равны :( –

+0

@EvgeniyKleban: вы поймете, когда-нибудь .. – Michael

+0

Я просто смущен в DIAERESIS, извините. В любом случае я ценю вашу помощь. –

Смежные вопросы