Игнорирование определенных строк при сортировке массива - PullRequest
2 голосов
/ 06 декабря 2010

Я подаю заявку на языки, и у меня есть длинный список словарного запаса, относящихся к этому языку (немецкий, на случай, если кому-то будет интересно).В моем приложении есть функция, позволяющая переключаться между сортировкой таблицы по немецким или английским словам.

Когда я использую следующее:

NSString *path = [[NSBundle mainBundle] pathForResource:name ofType:type];
NSString *string = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
NSArray *array = [[string componentsSeparatedByString:@"\n"] sortedArrayUsingSelector:@selector(compare:)];

, оно работает абсолютно идеально - благодаря чемуЯ имею в виду именно так, как и ожидалось.Однако я хотел бы улучшить это тем, что есть определенные слова, такие как глаголы или существительные, которым всегда предшествуют префиксы, такие как «к», как в «сделать что-то», или «the» передсуществительные.Поэтому я хотел бы как-то исключить их из своего рода, потому что в противном случае я получаю все глаголы, отсортированные по алфавиту в разделе «t» в моем массиве, что не очень удобно для пользователя.

Я просмотрел документацию Apple по NSString и NSArray, так как именно здесь находится функция compare (если я не сильно ошибаюсь), и я не нашел способа, который имел бы для меня смысл.Это первый раз, когда я выполняю такую ​​обработку данных, поэтому я могу упустить что-то простое, и поэтому я был бы очень признателен за помощь.

Большое спасибо

Michaeljvdw

Ответы [ 4 ]

4 голосов
/ 06 декабря 2010

Вы на правильном пути. Что вы хотите использовать вместо (встроенного) метода compare, это написать свой собственный метод, который может исключить биты «to» или «the», если они существуют, а затем использовать существующий метод compare.

Ваш звонок будет выглядеть примерно так:

NSArray *array = [[string componentsSeparatedByString:@"\n"] sortedArrayUsingSelector:@selector(myCompare:)];

Используя пользовательскую категорию, вы даете NSString следующими способами:

// This method can be exposed in a header
- (NSComparisonResult)myCompare:(NSString*)aString
{
 NSString* selfTrimmed = [self removeArticles];
 NSString* aStringTrimmed = [s2 removeArticles];
 return [self compare:aString];
}

// This method can be kept private in the .m implementation
- (NSString*)removeArticles
{
    NSRange range = NSMakeRange(NSNotFound, 0);
    if ([self hasPrefix:@"to "])
    {
     range = [self rangeOfString:@"to "];
    }
    else if ([self hasPrefix:@"the "])
    {
     range = [self rangeOfString:@"the "];
    }

 if (range.location != NSNotFound)
 {
  return [self substringFromIndex:range.length];
 }
 else
 {
  return self;
 }
}
1 голос
/ 06 декабря 2010

Во-первых, не используйте compare:.Вместо этого используйте localizedCompare:.Это важно, потому что ли á появляется сразу после a или после z как отдельная буква, зависит от языка.localizedCompare: позаботится об этом.

- edit

Как говорит Джастин, localizedStandardCompare: - это селектор, который будет использоваться!Я не знал этот метод.Как написано в документации, localizedStandardCompare: делает больше, чем localizedCompare:, хотя в документе точно не сказано, что он делает.

- конец редактирования

Если вам нужно большеВы должны реализовать это самостоятельно.Вы можете использовать категорию для этой цели.Сначала объявите его

  @interface NSString (MichaelsSuperCompareCategory)
       -(NSComparisonResult)michaelsSuperCompare:(NSString*)string;
  @end

, а затем реализуйте его

  @interface NSString (MichaelsSuperCompareCategory)
       -(NSComparisonResult)michaelsSuperCompare:(NSString*)string{
             ...
       }
  @end

Таким образом, вы можете добавлять методы в существующий класс.Затем вы можете использовать

NSArray *array = [[string componentsSeparatedByString:@"\n"] 
                                 sortedArrayUsingSelector:@selector(michaelsSuperCompare:)];

. Важно добавить префикс имени метода к чему-то отличительному, чтобы случайно не произойти сбой с внутренними методами, используемыми Apple.реализовать это самостоятельно, насколько я знаю.Вы можете получить текущую локаль с помощью [NSLocale currentLocale].Вы можете реализовать более приятное поведение для известных вам языков, а затем установить значение по умолчанию localizedCompare: для неизвестных языков.

1 голос
/ 06 декабря 2010

Возможно, вам повезет с localizedCompare: или localizedStandardCompare: , но я не думаю, что какой-либо из них удалит статьи и предлоги так, как вы хотите. Вместо этого вам, вероятно, придется определить категорию в NSString, которая обеспечивает определенный стиль сортировки, который вы ищете:

 @interface NSString (MySortAdditions)
 - (NSComparisonResult)compareWithoutArticles:(NSString *)other;
 @end

 @implementation NSString (MySortAdditions)
 - (NSComparisonResult)compareWithoutArticles:(NSString *)other {
    NSMutableString *mutableSelf = [NSMutableString stringWithString:self];
    [mutableSelf
        replaceOccurrencesOfString:@"das"
        withString:@""
        options:NSCaseInsensitiveSearch
        range:NSMakeRange(0, [mutableSelf length])
    ];

    ...

    // delete articles from 'other' too

    NSCharacterSet *trimSet = [NSCharacterSet whitespaceAndNewlineCharacterSet];
    NSString *trimmedSelf = [mutableSelf stringByTrimmingCharactersInSet:trimSet];
    NSString *trimmedOther = ...;

    return [trimmedSelf localizedCaseInsensitiveCompare:trimmedOther];
 }
 @end

Затем вы можете использовать @selector(compareWithoutArticles:) в качестве селектора сортировки для NSArray.

0 голосов
/ 06 декабря 2010

Я бы как-то сделал -replaceOccurancesOfStrings для всех данных, например "To" -> "" - и затем перезагрузил бы данные. (или это можно в текстовом редакторе)

Еще одна вещь, о которой стоит подумать, это изменить, например, «ходить» на «ходить (к)», что может быть сделано раньше времени (и это также создаст меньше путаницы для пользователя, поскольку они осуществляют прокрутку по алфавиту).

...