Как разделить NSString на более мелкие слова?

Привет,

Я новичок в цели c, и у меня есть следующая проблема:

У меня есть NSString:

 "There are seven words in this phrase"

Я хочу разделить это на 3 меньшие строки (и каждая меньшая строка может быть не длиннее 12 символов), но должна содержать целые слова, разделенные пробелом, так что я получаю:

String1 = "There are" //(length is 9 including space)
String2 = "seven words"// (length is 11)
String3 = "in this" //(length is 7), with the word "phrase" ignored as this would exceed the maximum length of 12..

В настоящее время я разбиваю свой исходный массив на массив с помощью:

NSArray *piecesOfOriginalString = [originalString componentsSeparatedByString:@" "];

Затем у меня есть несколько операторов «если» для сортировки ситуаций, когда есть 3 слова, но я хочу сделать это более расширяемым для любого массива до 39 (13 символов * 3 строки) букв, при этом любые символы> 40 игнорируются. Есть ли простой способ разделить строку на основе слов или «фраз» до определенной длины (в данном случае 12)?


person J. Dave    schedule 09.11.2009    source источник


Ответы (3)


Что-то похожее на это? (Предупреждение о сухом коде)

NSArray *piecesOfOriginalString = [originalString componentsSeparatedByString:@" "];

NSMutableArray *phrases  = [NSMutableArray array];
NSString *chunk = nil;
NSString *lastchunk = nil;

int i, count = [piecesOfOriginalString count];
for (i = 0; i < count; i++) {
    lastchunk = [[chunk copy] autorelease];

    if (chunk) {
        chunk = [chunk stringByAppendingString:[NSString stringWithFormat:@" %@", [piecesOfOriginalString objectAtIndex:i]]];
    } else {
        chunk = [[[piecesOfOriginalString objectAtIndex:i] copy] autorelease];
    }

    if ([chunk length] > 12) {
        [phrases addObject:lastchunk];
        chunk = nil;
    }

    if ([phrases count] == 3) {
        break;
    }
}
person Bryan McLemore    schedule 09.11.2009

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

person NSResponder    schedule 09.11.2009

Спасибо, МакЛемор, это действительно полезно! Я попробую это немедленно. Мое текущее решение очень похоже, но менее точно, так как я жестко закодировал циклы и использую отдельные переменные для хранения подстрок (называя их TopRow, MidRow и BottomRow), и проблема управления памятью упускается из виду...:

int maxLength = 12; // max chars per line (in each string)
int j=0; // for looping, j is the counter for managing the words in the "for" loop
TopRow = nil; //1st string
MidRow = nil; //2nd string
//BottomRow = nil; //third row string (not implemented yet)
BOOL Row01done = NO; // if YES, then stop trying to fill row 1
BOOL Row02done = NO; // if YES, then stop trying to fill row 2
largeArray = @"Larger string with multiple words";

tempArray = [largeArray componentsSeparatedByString:@" "];
for (j=0; j<[tempArray count]; j=j+1) {
    if (TopRow == nil) {
        TopRow = [tempArray objectAtIndex:j];
    }
    else {
        if (Row01done == YES) {
            if (MidRow == nil) {
                MidRow = [tempArray objectAtIndex:j];
            }
            else {
                if (Row02done == YES) {
                    //row 3 stuff goes here... unless I can rewrite as iterative loop...
                    //will need to uncommend BottomRow = nil; above..
                }                           
                else {
                    if ([MidRow length] + [[tempArray objectAtIndex:j] length] < maxLength) {
                        MidRow = [MidRow stringByAppendingString:@" "];
                        MidRow = [MidRow stringByAppendingString:[tempArray objectAtIndex:j]];
                    }
                    else {
                        Row02done = YES;
                        //j=j-1; // uncomment once BottowRow loop is implemented
                    }
                }
            }
        }
        else {
            if (([TopRow length] + [[tempArray objectAtIndex:j] length]) < maxLength) {
                TopRow = [TopRow stringByAppendingString:@" "];
                TopRow = [TopRow stringByAppendingString:[tempArray objectAtIndex:j]];
            }
            else {
                Row01done = YES;
                j=j-1; //end of loop without adding the string to TopRow, subtract 1 from j and start over inside Mid Row
            }
        }           
    }
}
person J. Dave    schedule 10.11.2009
comment
Да, это немного неприятно, я делаю все, что могу, чтобы мой код был неглубоким, он делает вещи более читабельными и удобными в сопровождении. - person Bryan McLemore; 10.11.2009